Friday, August 23, 2019

Typical expectation from a Microsoft Dynamics CRM Technical Developer


Dynamic CRM Related
  • Configure/customize all aspects of Microsoft Dynamics CRM
  • Configure the application to meet a client’s requirements using the Microsoft Dynamics CRM Customization Tool, Workflow Tool, Service Utility or SDK
  • Experience in developing CRM workflow, Custom Actions, Dialogs, Business Process Flows
  • Proficient in JavaScript/ TypeScript
  • Proficient in writing C# plug-ins using CRM and XRM SDK libraries
  • Proficient in writing client-side web resources utilizing Web API's for Dynamics CRM and extract records from entities using ODATA filters and uniquely identifying records with GUID


.Net and SQL Related
  • Web Services / WebApi / WCF
  • Proficient in writing Asynchronous programming with web services using AJAX and callback functions to extract responses in JSON objects
  • Experience in Creating reports MS SQL Server SSRS, Visual Studio, .NET and defining data integration layers using SSIS
  • Performance tuning, query optimization, and other performance and troubleshooting tools
  • 3rd Party Script Libraries such as JQuery / JQuery UI, Angular JS
  • Engineering web services using C#, WCF
  • Good knowledge of XML, XSL and XSD
  • Web Development using .NET, HTML5, CSS3, JavaScript, jQuery, Angular JS, XML and JSON with SQL database


Added Advantages - Not all are required, to be considered as a Bonus Point
  • Some experience with Azure Logic Apps
  • Power BI
  • Business Central
  • Unified Service Desk (USD)
  • Power Platform D365
  • On-Premise Installation or Migration from CRM 4/2011 to Dynamic 365 latest
  • Experience with Agile (specifically SCRUM methodology) as well as Waterfall models 
  • Good understanding of Azure (PaaS and SaaS)


Integration with Dynamic CRM - Not all are required, to be considered as a Bonus Point
  • QuickBooks
  • SharePoint
  • Dynamic 365 Portal (ADX Studio)
  • WordPress
  • Social Media - Linked-In / Facebook / Twitter 
  • Outlook Synchronization Setup
  • Any other ERP


Process Related 
  • Data Migration using Scribe or other Tools.
  • Business Process optimization 
  • Practical knowledge of SOA (Service Oriented Architecture)
  • Git, Jira, Confluence, Nunit



Regards,
Vipin Jaiswal


Typical expectation from a Microsoft Dynamics CRM Business Analyst


There seems to be confusion of roles and responsibilities between Dynamic CRM developer or technical lead and a business analyst who are involve in Dynamic CRM implementation.

Most of my friend who were in core development are shifting towards functional side of dynamic CRM.

Small and mid-scale business are cutting their cost by not involving BA in their project plans, but a BA does play a very important role.

Here in this blog, I would like to draft few expectations from Business Analyst that an organization are looking into.

Role and Responsibilities:
Microsoft CRM Business Analysts are responsible for identifying, developing and deploying end-user solutions in CRM systems. Using in-depth functional knowledge and familiarity with the Microsoft Dynamics CRM application, they need to ensure that client business requirements are met while providing a variety of advisory services around project management, business process development, implementation support and end-user training.

Duties:

Project Execution
• Support the translation of client business requirements into CRM solutions, including requirements approval, communication, traceability and reuse
• Contribute to the transfer of functional requirements to development and test teams
• Use CRM workflow technology to automate business processes
• Stay abreast on updates and new releases in CRM technologies (Microsoft’s and its competitors)
• Educate end-users on CRM functions
• Provide end user classroom training on the configured CRM application before go-live and individual training during hyper-support after the cut-over

Sales Support
• Help determine and translate customer needs into a solution and approach
• Contribute to proposal development
• Contribute to scope, approach, and estimating input to the proposal team
• Contribute to and participate in client demonstrations and presentations

Qualifications
• Microsoft dynamics certification (Refer below)
• Bachelor of Science preferably in Computer Science or Computer Engineering
• Microsoft Office Suite, specifically Microsoft Word, Excel, PowerPoint, and Visio
• Microsoft DevOps
• Familiarity with Microsoft technologies/trends
• Strong analytical, presentation, and writing skills
• Team lead or management experience of 5+ team members (management consultant only)
• Project experience in enterprise business application development and delivery (e.g., CRM, ERP, SCM, HCM)
• Project implementation experience using Microsoft Dynamics 365, Microsoft Dynamics CRM online, or Microsoft Dynamics CRM 2016, 2015, or 2013
• Project experience in translating client business needs into software capabilities
• Project experience with business requirements analysis and modeling
• Project experience in creating functional designs, test conditions and test scripts
• Basic knowledge of software development methodologies (Waterfall and/or Agile)



Advisable Certifications





  • MB-200 : Microsoft Dynamics 365 Customer Engagement Core
  • MB-210 : Microsoft Dynamics 365 for Sales
  • MB-220 : Microsoft Dynamics 365 for Marketing
  • MB-230 : Microsoft Dynamics 365 for Customer Service
For updated list - refer here 

Business Analyst Career Growth




The career growth of a Business Analyst further moved towards a Business Development Manager or a Sales Development Representative.

Business Analyst work and report closely to Delivery Head / Country Head and help them bringing more business in one organization.

Business Analyst help in estimation, building proposal and preparing sales collateral.

If any business analyst is looking to take long jump in his career, then he must have other ERP’s knowledge as well like Sugar CRM, Salesforce, Siebel CRM.

He must be through with latest pricing and key difference between various CRM available in the market.

Higher Responsibilities
  • Respond, engage and qualify inbound leads and inquiries
  • Engage current users to expand awareness, educate, ask for referrals, identify new opportunities and develop account intelligence
  • Schedule appointments and demos for Founder
  • Hold intelligent and engaging conversations over the phone and email
  • Act as the subject matter expert on product offerings/solution development skills
  • Effectively make use of core sales tools: Hubspot CRM, LinkedIn, Crunchbase, Google Apps, Microsoft Office
  • Collaborate with a distributed sales team
  • Capability of understanding customer pain points, requirements and correlating potential business
  • Strong and professional communication skills -- written, verbal, presentation
  • Aptitude to manage numerous requests and time demands concurrently, while achieving production goals from assigned territory or set of accounts
  • Promotes a strong sense of urgency for reaching goals and key deliverables. Acts without being told what to do. Brings new ideas to the company
  • Contributes fully to the team effort and plays an integral part in the smooth running of teams without necessarily taking the lead
  • Drive, Grit, Team Oriented: strong desire to compete and win


Refer here for Expectation and skill set required for CRM Technical Developer
https://vjcity.blogspot.com/2019/08/typical-expectation-from-microsoft_23.html



Please let me know if you would like to add few more point which I might missed here.

Regards,
Vipin Jaiswal
vipinjaiswal12@gmail.com

Friday, August 16, 2019

Best Practise to write JavaScript in Microsoft Dynamic CRM


Naming your Web-Resource

Prefix_/EntityName/SpecificPurpose/[version].js

Few examples:
  • msdyn_/SalesInsightsConfig/Resources/Globalization.1025.js
  • new_/invoice/cancelAllContractNotificationOnRenewal.js
  • msdyn_/solutionlayers/static/js/main.js
  • new_/Quote/CreateDuplicateQuote.js

Note: It is important to consider having our own publisher where we can define our prefix to be used in all web-resource.


Commenting your Code

File comment to denote why, when and by whom its been created.

/********************** Source File Header **************************
Project Name: Clinic_ZZZZZ

Creation Date: 4th Feb 2018
Created By: vjCity \ Vipin Jaiswal
Last Modification Date: 27th Feb 2018
Last Modified By: vjCity \ Vipin Jaiswal
Version: 1.0.0.0
Purpose: Common JS Library
********************************************************************/

Going further in the blog you will notice how comments help us in understanding our code better.


Coding Style – Modular vs Object Oriented

When writing any helper class which is going to be used across all entities, I suggest going with Object Oriented way as we get a benefit of having our own namespace. There are two style of having object-oriented JavaScript code:
Explicit Namespace Declaration and using .(Dot) to have classification

// declare the default namespace
if (vjCity === undefined) {
    var vjCity = {};
}
/// The cached user role
var cachedUserRole = new Array();

////////////////////Global Values////////////////////
vjCity.ERRORNotification = "ERROR";
vjCity.WarningNotification = "WARNING";
vjCity.INFONotification = "INFO";

//*******************Dialogs*************************
vjCity.changePasswordDialogId = "C3E7C5CD-AEF7-4DE7-8483-FBDF494F1A04";
vjCity.submitBusinessIdeaDialogId = "1A7A07C8-6B21-48DB-8BB4-1199451086E3";

//*******************Workflows***********************
vjCity.SubmitCommitteeDecisionsWorkflowId = "E2D77408-4A98-43D0-8856-ABEDEB8537D4";
vjCity.MembershipRequest_WorkflowId = "6F327E10-B358-4332-85F4-18D08C16F076";
vjCity.MembershipRequest_TransferToSupportWorkflowId = "5FDAA058-2301-43E6-B82E-7300339529E9";


/*
* Retrieve data
* Id = Id of the record
* type = Entity logical name
* select = fields to be retrieved ex: "new_A,new_B"
* callback = callback function
* example how to call this function :
***********************************************
var obj = Xrm.Page.getAttribute("exkb_client").getValue();
    if (obj === null) return;
    getDataById(obj[0].id, 'exkb_client', 'exkb_clientId, exkb_ClientContact', function(o)
    {
        if(!!o)
            Xrm.Page.getAttribute("customerid").setValue([{id: o.exkb_ClientContact.Id, name:o.exkb_ClientContact.Name, entityType:'contact'}]);
    });
***********************************************
*/
vjCity.getDataById = function (id, type, select, callback) {
    var serverUrl = Xrm.Page.context.getClientUrl();
    var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + type + "Set(guid'" + id + "')?$select=" + select;
    var req = new XMLHttpRequest();
    req.open("GET", oDataSelect, false);
    req.setRequestHeader("Accept""application/json");
    req.setRequestHeader("Content-Type""application/json;charset=utf-8");
    req.onreadystatechange = function () {
        if (req.readyState === 4) {
            if (req.status === 200) {
                callback(JSON.parse(req.responseText).d);
            }
        }
    };
    req.send();

};


All Code within curly bracket ( )

// declare the default namespace
if (vjCity === undefined)
{
  var vjCity =
  {
    ////////////////////Global Values////////////////////
    ERRORNotification = "ERROR";
    WarningNotification = "WARNING";
    INFONotification = "INFO";

    //*******************Dialogs*************************
    changePasswordDialogId = "C3E7C5CD-AEF7-4DE7-8483-FBDF494F1A04";
    submitBusinessIdeaDialogId = "1A7A07C8-6B21-48DB-8BB4-1199451086E3";

    //*******************Workflows***********************
    SubmitCommitteeDecisionsWorkflowId = "E2D77408-4A98-43D0-8856-ABEDEB8537D4";
    MembershipRequest_WorkflowId = "6F327E10-B358-4332-85F4-18D08C16F076";
    MembershipRequest_TransferToSupportWorkflowId = "5FDAA058-2301-43E6-B82E-7300339529E9";


    /*
    * Retrieve data
    * Id = Id of the record
    * type = Entity logical name
    * select = fields to be retrieved ex: "new_A,new_B"
    * callback = callback function
    * example how to call this function :
    ***********************************************
    var obj = Xrm.Page.getAttribute("exkb_client").getValue();
        if (obj === null) return;
        getDataById(obj[0].id, 'exkb_client', 'exkb_clientId, exkb_ClientContact', function(o)
        {
            if(!!o)
                Xrm.Page.getAttribute("customerid").setValue([{id: o.exkb_ClientContact.Id, name:o.exkb_ClientContact.Name, entityType:'contact'}]);
        });
    ***********************************************
    */
    getDataById = function (id, type, select, callback) {
        var serverUrl = Xrm.Page.context.getClientUrl();
        var oDataSelect = serverUrl + "/XRMServices/2011/OrganizationData.svc/" + type + "Set(guid'" + id + "')?$select=" + select;
        var req = new XMLHttpRequest();
        req.open("GET", oDataSelect, false);
        req.setRequestHeader("Accept""application/json");
        req.setRequestHeader("Content-Type""application/json;charset=utf-8");
        req.onreadystatechange = function () {
            if (req.readyState === 4) {
                if (req.status === 200) {
                    callback(JSON.parse(req.responseText).d);
                }
            }
        };
        req.send();
    };
  };
}

Modular Approach to JavaScript

This is most straight forward way of coding and we can use this style when we are writing entity specific code and we just need declaration of methods.

An Example:

///
/*
Date created : 10 Jan 2018
Name : Vipin Jaiswal
Last updated : 13 Feb 2018
Purpose : JS Library for Applicant(Contact) Entity
*/


//****************** Global Value ******************************
var entityName = "contact";
var recordId = Xrm.Page.data.entity.getId();

//*************** Form Methods Start ****************************

function form_OnLoad()
{
    SetDocumentFrame("IFRAME_documents");
    CheckMembershipExpiry();
    CheckEstablishment();
    var val = Xrm.Page.getAttribute("address1_postofficebox").getValue();
    Xrm.Page.getAttribute("address1_postofficebox").setValue(ValidatePOBox(val));
}

function form_OnSave()
{

}

//************ Ribbon Methods ***********************************
function changePasswordCallDialog()
{
    //Call the change password dialog
    Alert.showDialogProcess(changePasswordDialogId, entityName, recordId);
}
function bulkCreateCommitteeSessions()
{
    // Call the bulk create committee sessions
    Alert.showDialogProcess(bulkCreateCommitteeInstances, entityName, recordId);
}

//************* On Change Methods *************************
function EmploymentStatusOnChange() {
    CheckEstablishment();
}
function EmariteIdOnChange() {
    ValidateEmiratesId(Xrm.Page.getAttribute("kfexc_emiratesid").getValue());
}
function PassportExpiryDateOnChange() {
    var passportExprity = Xrm.Page.getAttribute("kfexc_passportexpirydate").getValue();
    if ((passportExprity !== null || passportExprity !== undefined) && vjCity.dateIsLater(Date.now(), passportExprity)) {
        vjCity.showFormNotification("Passport is Expired", vjCity.WarningNotification, "1");
    }
    else
        vjCity.clearFormNotification("1");
}

function BirthdateOnChange() {
    var birthdate = Xrm.Page.getAttribute("birthdate").getValue();
    if ((birthdate !== null || birthdate !== undefined) && vjCity.dateIsLater(birthdate, Date.now())) {
        vjCity.showFormNotification("Birth Date is in the future", vjCity.WarningNotification, "3");
    }
    else
        vjCity.clearFormNotification("3");
}
function MobileNumberOnChange() {
    var mobNumber = Xrm.Page.getAttribute("mobilephone").getValue();
}
function HomeNumberOnChange() {
    var Number = Xrm.Page.getAttribute("address1_telephone1").getValue();
    vjCity.ValidateMobileNumber(Number, "address1_telephone1");
}


//
//*************** Business Validation Methods **************

function ValidateEmiratesId(txt) {
    if (txt === "")
        return;
    var patt = new RegExp("^[0-9]{15}$");
    var res = patt.test(txt);

    if (!res || !txt.startsWith("784")) {
        vjCity.showFieldNotificiation("kfexc_emiratesid""Emirates Id format is invalid");
    }
    else {
        vjCity.clearFieldNotification("kfexc_emiratesid");
        var a = "";
        for (var i = 0; i < txt.length ; i++) {
            switch (i) {
                case 2:
                    a = a + txt[i] + "-";
                    break;
                case 6:
                    a = a + txt[i] + "-";
                    break;
                case 13:
                    a = a + txt[i] + "-";
                    break;
                default:
                    a = a + txt[i];
            }
        }
        Xrm.Page.getAttribute("kfexc_emiratesid").setValue(a);
    }
}

function ValidatePOBox(val)
{
    if (val !== undefined && val != null)
        return val.replace("-""");
    return "";
}


I hope there are better approach to have perfect coding style, please do let me know if you came across any in comments.

Thanks,
Vipin Jaiswal
vipinjaiswal12@gmail.com