Tuesday, December 25, 2018

Configure email synchronization and Mailboxes on Microsoft Dynamics CRM 365 Online


Before I proceed with configuring mail box and server profile, I would like to first talk about some of the important configuration that is surely missed by any system administrator.

As a System Administrator, it is advisable to first configure Global Email Configuration Settings which would be applied to all users in Microsoft Dynamic CRM.


Navigate to Settings >> Email Configuration >> Email Configuration Settings.


Configure default synchronization method, which would be applied to all the mailboxes of newly created users and queues. It is possible to have different settings based on our organization needs.


Point to Note: Only a Global Administrator can approve an email of any user in Dynamic CRM and then only a user would be able to send and receive email communication.

I prefer to Un-tick the option of Process emails only for approved users, so that user who is system administrator in Dynamic CRM can also configure mailbox and make user functional. No need to rely on Global Administrator to approve individual emails all the time.


CRM by default append an Email Token in all email subjects which are sent out from Dynamic CRM. Most business doesn’t like to have such token to be a part of email subject or headline. In order to remove that, we need to Un-tick the use correlation to track email conversation.

Configure mailboxes

Go to Settings >> Email Configuration >> Mailboxes.
Open the mail box of the respective user which we might be interested in providing email communication functionality.

First -> Approve email (if not done in global setting)
Second -> Test & Enable Mailboxes



When you click Test & Enable Mailbox, CRM verifies that the mailbox is configured correctlyAlso a respective user should receive a test mail for confirmation of successful configuration.


To test your users’ mailboxes or several mailboxes at the same time:
  • Go to Settings > Email Configuration > Mailboxes.

In this view, you’ll see all the mailboxes your role allows you to access. You can select multiple mailboxes and test and enable them together.

Errors in configuring mailbox need to do more troubleshooting.

It’s important to understand that the test and enable action doesn’t take place immediately. If successful, it can take up to 15 minutes to complete. 
First, you can go to the mailbox itself. As displayed in the screen shot below, test and enable results appear on the alert wall of the mailbox.


There could be error message on the alert wall, only after looking at the respective error message we can do troubleshooting.

Regards,
Vipin Jaiswal

Manage a user in Microsoft Dynamic 365 CRM Online


Following is broad category to configure a user in Dynamic CRM.
  • First, create a user in Active Directory and assign him respective dynamic CRM license.
  • Second, Assign security role to a user in Dynamic CRM
  • Configure and test user mail box


Create a user in Active Directory and assign him respective dynamic CRM license.

Login to Online CRM or Office 365 instance using Global Admin credentials.
Go to Admin Settings.

Go to “Add a user” Section.



Fill-in the required information for New User forms and provides personal details and contact information of the user.


Create a password and optionally you can select to change the password by the user itself when they sign in first time.

Select the respective role according to business needs. Mostly for common use we are supposed to select User (no administrator access)


Assign user a license accordingly under Dynamic 365 Customer Engagement Plan. This could be different based on the license option obtain by you organization.


BINGO! We have new user on Active Directory.

Please note: User creation and assign a dynamic CRM License require few minutes of synchronization for a User to be created in Dynamic CRM online. You should see a user in Dynamic CRM by navigating to 
Settings -> security -> Users
Once the new user is reflect in Dynamic CRM instance, we will proceed with next step to assign user a security role.

Select the new user and click on Manage Roles. This will pop up – Manage Users Roles window. Select the desired security role and click OK to assign the security role to the new user.



After this step is done User would be able to login to Dynamic CRM and perform all functional tasks within it. But a user should also be able to do communication with client and other member of the team. For this it is also important to configure user a mail box.


Thanks.
Vipin Jaiswal

vipinjaiswal12@gmail.com


Saturday, December 15, 2018

MSCRM Best Practice - Considering Out-Of-Box Entities as preferred choice


I was working with one of my client where they have implemented Dynamic CRM for HR module. In a typical HR module the core entity is employee entity which is related with all other different entity such as Employee Leave Request, Employee Leave Approval, etc. I am not trying to explain how HR module works or any of its features in this blog post.

I would rather like to drive attention on how the approach and the mindset one must have for consuming out of the box entity and dynamic CRM functionality when implementing any business domain/vertical/module in Microsoft Dynamic CRM.

Account and Contact




Vanilla CRM comes with many default entities and the most crucial entities among them are Account and contact. The project that I was asked to review has implemented HR module in dynamic CRM and created employee as a custom entity, instead of considering contact to be as an employee.
  • I am aware and understand that there is no direct employee entity that comes with vanilla dynamic CRM.
  • Microsoft doesn’t have any guidelines which say when to use what entity.
  • So it would be very normal for someone to simply go ahead and creates a custom entity for whatever purpose he likes.
  • But the question arises - can we not use contact entity instead of creating custom employee entity?

Let’s talk about some of the pain that we may have to bear if we are not using core entities of dynamic CRM and creating our own custom entity instead.


Dynamic 365 portals / ADX portal implementation in near future.




Let’s consider after one year of implementations client ask to have employee self-login portal. We would be deprived with most of the features which Dynamic Portal provides as it has been designed by keeping core entities in mind.
If we consider contact entity for employee and install customer self-service portal, we would be benefited completely with most basic features which comes as out of the box.
  1. Employee can login and manage their credentials and personal information like email and phone number.
  2. The authentication and security model is all around contact entity and if we are not using contact and going with custom employee entity, then we need to have our own custom authentication and access management. This is re-inventing the wheel and waste of time and development efforts.
The list goes on as Dynamic 365 portal are purely implemented considering core entities in dynamic CRM. 


Marketing and Campaign




For campaign, we are supposed to create a marketing list and marketing list in dynamic CRM can only point to three entities which are Leads, Contacts and Accounts. There is no splendid path to bring a custom entity to be a part of marketing list. If we think of HR module where we want to inform employee about various organization policies could be easily achieved using campaign module. But this special out of the box features would be useless if we are not considering contact entity to be treated as employee entity.


Customer Service Modules




The service module in CRM evolves with logging of cases in dynamic CRM. By default incident and other related entities like entitlements are all related to contact and account entity. So again it is in our favor to stick with core CRM entities to enjoy the benefit of CRM completely.


No benefit of new features and Updates from Microsoft Team




Once we choose a path of creating a custom entity we start moving away from not only what’s been already provided in dynamic CRM, we also don’t get any benefit from a constant new features that are added by Microsoft Team and community. Any updates from Microsoft Dynamic CRM Development Team would be made considering the vanilla product provided not to any specific customer implementation.


Considering the use of out of the box entities and understanding vanilla CRM in its original form is also important to get best result implementing Dynamic CRM for any organization.


Regards,
Vipin Jaiswal
vipinjaiswal12@gmail.com

Tuesday, December 4, 2018

Web Forms & Web Form Steps in Dynamic 365 Portal


I have prepared a short video tutorial to explain how to implement web form and web form steps in Dynamic 365 portal.

Business Scenario:
An email invite would be sent to customer to participate in training events. A customer can click on the email invite link and that will open up Dynamic portal web page, which have series of steps for customer to self-register.

There are few conditions in the registration process and we are trying to capture the user input and the next step is decided based on the user input.

CRM Technical : Web Form and Web Form Steps

A web page is the portal page which would be treated as a container and will render our web form components within it.
A web page can have only one web form component and within web form component, we can have multiple web form steps.



These web form steps can be of different types such as Load, redirect, conditional, load tab and user control.



Tutorial Link





Thanks.
Vipin Jaiswal
Vipinjaiswal12@gmail.com

Saturday, December 1, 2018

Generic utility to Copy Notes and attachment in Microsoft Dynamic 365 CRM


How to Copy notes/attachments from one Entity to another, when there is a One to Many relationship exists between them.

To illustrate we have Account with many Contacts and would like to have all notes n attachment copied from its parent account when contact is created.

Here are the configuration steps, (workflow code is at the end)

Step 1) Create a new workflow processes, so we can call the custom workflow assembly and set its parameter accordingly.



Step 2) Need to set parameter as
Source Attribute Name : parentcustomerid
Target Entity Name              : contact



Demo Steps

Step 1) Create an Account record and attach file in notes and click save.


Step 2) Create child Contact records and Observe Notes and attachment gets the attachment from parent account record.




The workflow Code

public sealed class CopyNotesWorkflow : CodeActivity
{
    #region Workflow Parameters

        [RequiredArgument]
        [Input("Source Attribute Name")]
        public InArgument<string> SourceAttributeName { get; set; }

        [RequiredArgument]
        [Input("Target Entity Name")]
        public InArgument<string> TargetEntityName { get; set; }

    #endregion Input Parameters


    protected override void Execute(CodeActivityContext executionContext)
    {
    #region Manage Tracing and Organization Service
    // Create the tracing service
    ITracingService tracingService = executionContext.GetExtension<ITracingService>();

    if (tracingService == null)
    {
        throw new InvalidPluginExecutionException("Failed to retrieve tracing service.");
    }

    tracingService.Trace("Entered CopyNotes.Execute(), Activity Instance Id: {0}, Workflow Instance Id: {1}",
        executionContext.ActivityInstanceId,
        executionContext.WorkflowInstanceId);

    // Create the context
    IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();

    if (context == null)
    {
        throw new InvalidPluginExecutionException("Failed to retrieve workflow context.");
    }

    tracingService.Trace("CopyNotes.Execute(), Correlation Id: {0}, Initiating User: {1}",
        context.CorrelationId,
        context.InitiatingUserId);

    IOrganizationServiceFactory serviceFactory = executionContext.GetExtension<IOrganizationServiceFactory>();
    IOrganizationService orgService = serviceFactory.CreateOrganizationService(context.UserId);

    #endregion

    try
    {
        var sourceAttribute = this.SourceAttributeName.Get(executionContext);
        var targetEntity = this.TargetEntityName.Get(executionContext);


        if (context.InputParameters.Contains("Target") && context.InputParameters["Target"] is Entity)
        {
            Entity reqResponse = (Entity)context.InputParameters["Target"];

            if (!reqResponse.Attributes.Contains(sourceAttribute))
                throw new InvalidPluginExecutionException("Source Relationship Not found !!!");

            var accountId = ((EntityReference)(reqResponse.Attributes[sourceAttribute])).Id;

            // Fetch all Notes and Attachment for associated Leave Request
            QueryExpression Notes = new QueryExpression { EntityName = "annotation", ColumnSet = new ColumnSet(true) };
            Notes.Criteria.AddCondition("objectid", ConditionOperator.Equal, accountId);
            EntityCollection NotesRetrieve = orgService.RetrieveMultiple(Notes);

            if (NotesRetrieve.Entities.Count > 0)
            {
                // For all Notes n Attachments retrieved, loop and create new duplicate notes.
                foreach (var entity in NotesRetrieve.Entities)
                {
                    Entity note = new Entity("annotation");
                    note["objectid"] = new EntityReference(targetEntity, reqResponse.Id);
                    note["objecttypecode"] = targetEntity;// Associate Notes to Request Response

                    if (entity.Attributes.Contains("isdocument"))
                        note["isdocument"] = entity["isdocument"];

                    if (entity.Attributes.Contains("notetext"))
                        note["notetext"] = entity["notetext"];

                    if (entity.Attributes.Contains("filename"))
                        note["filename"] = entity["filename"];

                    if (entity.Attributes.Contains("documentbody"))
                        note["documentbody"] = entity["documentbody"];

                    if (entity.Attributes.Contains("mimetype"))
                        note["mimetype"] = entity["mimetype"];

                    orgService.Create(note);
                }
            }
        }
    }
    catch (Exception ex)
    {
        throw new InvalidPluginExecutionException(ex.ToString(), ex);
    }
    }

}


Some other commonly used examples are Lead to Opportunity.

Configuration for such would be




Thanks.
Vipin Jaiswal
Vipinjaiswal12@gmail.com

Guidelines to write good JavaScript code in Microsoft Dynamic CRMhttps://vjcity.blogspot.com/2019/08/guidelines-to-write-good-javascript.html