Friday, December 9, 2011

Avoid duplicates when creating / updating records using the CRM SDK

When you enable duplicate detection and publish your duplicate detection rules, you will notice that when you try to create a duplicate in the CRM web application (or through Outlook client) you will get a pop-up indicating that you are trying to create a duplicate record. However, if the create/update request is sent via the web services to CRM (using the SDK) then by default, the duplicate record will be created without any warning.

The trick is that if you want to avoid creating duplicates when calling the CRM web services, you need to provide an optional parameter in the request which specifies that the server should check for duplicates before creating your record (by default the server will bypass duplicate detection). You must use a CreateRequest or UpdateRequest and provide the SuppressDuplicateDetection as “false”. Here is a sample for which my code will prevent creating duplicate accounts (note that I have already published a duplicate detection rule for accounts with the same name):

 

Account a = new Account();
a.Name = "My account";

CreateRequest req = new CreateRequest();
req.Parameters.Add("SuppressDuplicateDetection", false);
req.Target = a;
try
{
    service.Execute(req);
}
catch (FaultException<OrganizationServiceFault> ex)
{
    if (ex.Detail.ErrorCode == -2147220685)
    {
        // Account with name "My account" already exists
    }
    else
    {
        throw;
    }
}

Monday, November 28, 2011

How to access CRM from different user accounts at the same time

Many times when you are testing CRM you need to access the web application from multiple test users. It is a bit annoying to have to log out of Windows and log in with another user to test something in the CRM application. Here is a trick on how you can access CRM (OnPremise, IFD, Online) from different users at the same time (in different IE windows):

While pressing down the “Shift” key, right-click on the Internet Explorer icon and select “Run as a different user”:

image

 

For OnPremise CRM: Enter the credentials of the user which you want to test CRM with. When you go to the CRM site, you should be automatically logged in as the user that you selected to run Internet Explorer as. You can open as many IE sessions with as many different users as you want!

For IFD / CRM Online: For each CRM user that you want to test you need to enter the credentials for any existing user (domain or local user). Then you can navigate to the CRM login site and enter the CRM credentials for the user you want to test. You can also open as many sessions with different users as you want.

For CRM for Outlook: Unfortunately you cannot execute multiple simultaneous Outlook windows using different users (at least not that I know about).

 

I have found this trick quite helpful and now I find myself logged in to CRM with multiple users at the same time so I can test things like security roles, email, etc.

Monday, October 31, 2011

How to “un-share” CRM records using workflow.

I posted earlier this year about how to share records using workflow in CRM 2011. Since then, I have got multiple requests to support “un-share” or revoking privileges to a record through CRM workflow. I have updated the CRM 2011 Workflow Utilities solution to support unsharing of records. It works very similar to the “share” step.

image_2

An unshare step is used in order to “unshare” or revoke shared privileges to the primary entity of the workflow (or a related entity) with a user or team. You must specify which record you want to unshare (primary vs. related). You can specify who you want to unshare the record with (user and/or team). Note that you can specify both a user and a team, in which case the record will be unshared with both. If you don’t specify any user/team then the record will be unshared with everyone with whom the record is currently shared. The configuration (input parameters) of the “unshare” step are similar to the share step. You can download the solution and read the documentation in the CodePlex site here.

Wednesday, October 12, 2011

Which entities are available in CRM process designer (workflows / dialogs) ?

It has often been asked why you cannot find a specific entity in the process designer. For example you might want to update and article from a workflow but you will notice that the process designer in CRM will not allow you to do that because the article entity will not be available.

So what does that mean?
There are special entities in CRM which are not supported in processes. For example, workflow does not support editing or creating articles because there is a special process for approving and publishing articles which the CRM workflow cannot handle.

How do I know if my entity is supported by workflow?
Each entity type in CRM has a read-only attribute called “WorkflowSupport”. This attribute will indicate the different levels of support that the entity has in a workflow. Additionally, there is the boolean “CanTriggerWorkflow” attribute which indicates whether the entity can be the primary entity of a process (whether a process can be defined on that entity).

Which are the different support levels for an entity in workflow and what do they mean?
Level Description
1
On-demand workflows can be defined for this entity
2 This entity can be created in a process “Create” step.
4 This entity can be updated in a process “Update” step.
8 Workflow can send email from an email template for this entity.
An entity can have zero or more supported levels above. The “WorkflowSupport” attribute of the entity will contain the sum of all the levels which are supported for that specific entity. For example, the entity “annotation” (Note) has workflow support of 11 which means that it supports level 1, 2 and 8 (1+2+8 =11). Therefore the entity has all the workflow support except level 4, so you cannot edit a note in an “update” step of a process.

If the entity does not have the workflow support that I need, how can I update it?
Updating the WorkflowSupport or CanTriggerWorkflow attributes of an entity is unsupported and should never be done, there is a reason why the workflow support is the way that it is. You can read more about the risks of unsupported customizations here. You will need to consider using a plugin instead of a workflow/dialog to perform the action that you need. In some cases you could also use a custom workflow activity to implement your logic.

What is the WorkflowSupport for custom entities?
Custom entities have WorkflowSupport of 15 so they support all workflow support levels (1+2+4+8). They will also have the CanTriggerWorkflow attribute set to true.

What is the WorkflowSupport and CanTriggerWorkflow value for each entity?
The following list provides the values for each entity in CRM 2011:

Can Trigger Workflow
Workflow Support
Entity Name
1
15
Account
0
0
AccountLeads
0
0
ActivityMimeAttachment
0
0
ActivityParty
0
0
ActivityPointer
1
11
Annotation
0
0
AnnualFiscalCalendar
0
0
ApplicationFile
1
15
Appointment
0
0
AsyncOperation
0
0
Attachment
0
0
AttributeMap
0
0
Audit
0
0
BulkDeleteFailure
0
0
BulkDeleteOperation
0
0
BulkOperation
0
0
BulkOperationLog
1
1
BusinessUnit
0
0
BusinessUnitMap
1
1
BusinessUnitNewsArticle
0
0
Calendar
0
0
CalendarRule
1
15
Campaign
1
15
CampaignActivity
0
0
CampaignActivityItem
0
0
CampaignItem
1
15
CampaignResponse
0
0
ClientUpdate
0
0
ColumnMapping
0
0
Commitment
1
15
Competitor
0
0
CompetitorAddress
0
0
CompetitorProduct
0
0
CompetitorSalesLiterature
1
15
Connection
1
1
ConnectionRole
0
0
ConnectionRoleAssociation
0
0
ConnectionRoleObjectTypeCode
1
1
ConstraintBasedGroup
1
15
Contact
0
0
ContactInvoices
0
0
ContactLeads
0
0
ContactOrders
0
0
ContactQuotes
1
15
Contract
1
1
ContractDetail
1
1
ContractTemplate
1
1
CustomerAddress
1
1
CustomerOpportunityRole
1
1
CustomerRelationship
0
0
Dependency
0
0
DependencyNode
1
1
Discount
1
1
DiscountType
0
0
DisplayString
0
0
DisplayStringMap
0
0
DocumentIndex
0
0
DuplicateRecord
0
0
DuplicateRule
0
0
DuplicateRuleCondition
1
15
Email
0
0
EmailHash
0
0
EmailSearch
0
0
EntityMap
1
1
Equipment
1
15
Fax
0
0
FieldPermission
0
0
FieldSecurityProfile
0
0
FilterTemplate
0
0
FixedMonthlyFiscalCalendar
1
15
Goal
1
1
GoalRollupQuery
0
0
Import
0
0
ImportData
0
0
ImportEntityMapping
0
0
ImportFile
0
0
ImportJob
0
0
ImportLog
0
0
ImportMap
1
15
Incident
0
0
IncidentResolution
0
0
IntegrationStatus
0
0
InternalAddress
0
0
InterProcessLock
0
0
InvalidDependency
1
15
Invoice
1
1
InvoiceDetail
0
0
IsvConfig
1
1
KbArticle
1
1
KbArticleComment
1
1
KbArticleTemplate
1
15
Lead
0
0
LeadAddress
0
0
LeadCompetitors
0
0
LeadProduct
1
15
Letter
0
0
License
1
15
List
0
0
ListMember
0
0
LookUpMapping
1
1
MailMergeTemplate
1
1
Metric
0
0
MonthlyFiscalCalendar
0
0
Notification
1
15
Opportunity
0
0
OpportunityClose
0
0
OpportunityCompetitors
1
1
OpportunityProduct
0
0
OrderClose
0
0
Organization
0
0
OrganizationStatistic
0
0
OrganizationUI
0
0
Owner
0
0
OwnerMapping
1
15
PhoneCall
0
0
PickListMapping
0
0
PluginAssembly
0
0
PluginType
0
0
PluginTypeStatistic
1
1
PriceLevel
0
0
PrincipalAttributeAccessMap
0
0
PrincipalEntityMap
0
0
PrincipalObjectAccess
0
0
PrincipalObjectAttributeAccess
0
0
Privilege
0
0
PrivilegeObjectTypeCodes
0
0
ProcessSession
1
15
Product
0
0
ProductAssociation
1
1
ProductPriceLevel
0
0
ProductSalesLiterature
0
0
ProductSubstitute
0
0
Publisher
0
0
PublisherAddress
0
0
QuarterlyFiscalCalendar
1
15
Queue
1
15
QueueItem
1
15
Quote
0
0
QuoteClose
1
1
QuoteDetail
0
0
RecurrenceRule
1
9
RecurringAppointmentMaster
1
1
RelationshipRole
0
0
RelationshipRoleMap
1
1
Report
0
0
ReportCategory
0
0
ReportEntity
0
0
ReportLink
0
0
ReportVisibility
0
0
Resource
0
0
ResourceGroup
0
0
ResourceGroupExpansion
0
0
ResourceSpec
0
0
RibbonCommand
0
0
RibbonContextGroup
0
0
RibbonCustomization
0
0
RibbonDiff
0
0
RibbonRule
0
0
RibbonTabToCommandMap
0
0
Role
0
0
RolePrivileges
0
0
RoleTemplate
0
0
RoleTemplatePrivileges
1
1
RollupField
1
15
SalesLiterature
1
1
SalesLiteratureItem
1
15
SalesOrder
1
1
SalesOrderDetail
0
0
SalesProcessInstance
0
0
SavedQuery
0
0
SavedQueryVisualization
0
0
SdkMessage
0
0
SdkMessageFilter
0
0
SdkMessagePair
0
0
SdkMessageProcessingStep
0
0
SdkMessageProcessingStepImage
0
0
SdkMessageProcessingStepSecureConfig
0
0
SdkMessageRequest
0
0
SdkMessageRequestField
0
0
SdkMessageResponse
0
0
SdkMessageResponseField
0
0
SemiAnnualFiscalCalendar
1
5
Service
1
15
ServiceAppointment
0
0
ServiceContractContacts
0
0
ServiceEndpoint
1
15
SharePointDocumentLocation
1
15
SharePointSite
1
15
Site
0
0
SiteMap
0
0
Solution
0
0
SolutionComponent
0
0
StatusMap
0
0
StringMap
1
1
Subject
0
0
Subscription
0
0
SubscriptionClients
0
0
SubscriptionManuallyTrackedObject
0
0
SubscriptionSyncInfo
0
0
SubscriptionTrackingDeletedObject
0
0
SystemForm
1
13
SystemUser
0
0
SystemUserBusinessUnitEntityMap
0
0
SystemUserLicenses
0
0
SystemUserPrincipals
0
0
SystemUserProfiles
0
0
SystemUserRoles
1
15
Task
1
1
Team
0
0
TeamMembership
0
0
TeamProfiles
0
0
TeamRoles
1
1
Template
1
15
Territory
0
0
TimeZoneDefinition
0
0
TimeZoneLocalizedName
0
0
TimeZoneRule
1
1
TransactionCurrency
0
0
TransformationMapping
0
0
TransformationParameterMapping
0
0
UnresolvedAddress
0
0
UoM
0
0
UoMSchedule
0
0
UserEntityInstanceData
0
0
UserEntityUISettings
0
0
UserFiscalCalendar
0
0
UserForm
0
0
UserQuery
0
0
UserQueryVisualization
0
0
UserSettings
0
0
WebResource
0
0
WebWizard
0
0
WizardAccessPrivilege
0
0
WizardPage
0
0
Workflow
0
0
WorkflowDependency
0
0
WorkflowLog
0
0
WorkflowWaitSubscription