Getting Started with the USD

If you have not used the USD in Dynamics365 then you’re missing out.

If you’re stuck on how to get started the process is relatively simple and primarily involves downloading the framework and deploying it to your tenant.

To start, download the require components – you will need the framework geared to your OS as well as the Package Deployer- which are all available here – https://www.microsoft.com/en-us/download/details.aspx?id=50355

If you try to open the USD without running the Package Deployer, you’ll receive the following error.

dynamics2

When you execute the Package Deployer, it will ask you where you want to deploy the USD’s solution files to.

dyanmics3

Next you’ll need to selection which package you want to import.  For now – go with the “New Environment” package.

Dynamics4

Once selected, you’ll wait for the solutions to be installed.

Dynamics5

Followed by all the post execution tasks to be executed.Dynamics6

Now if you go back and click the USD icon on your desktop, you’ll get this wonderfully empty canvas from which you can start implementing your solution.

Dynamics7

For now though, you are ready to go.

 

Visual Studio Compatibility

If you’re like me and spend most of your time in Visual Studio, being kicked out to open a Work Item can be an unwelcome window popup and waiting for something to load (that doesn’t need to).

Translation: When I’m in Visual Studio, working in Visual Studio, I don’t need my bugs to open in a browser.

Thankfully this is easy to change.

vs

Creating a Custom Interactive button in Dynamics

It’s been awhile since I played with the Ribbon Workbench and I had to re-familiarize myself with it to deploy some custom button functionality to a Dynamics tenant.

If you’re not familiar with the Ribbon Workbench, go download it and bask in it’s glory and time saving capabilities.

Once you install the solution into your Dynamics system, usage is as simple as selecting the solution you want your new button to be deployed to, dragging a button onto the Form toolbar and creating a command object that calls a function in your specified JavaScript file.

Creating the Button

As you can see from the screenshot, my function is called SendMail and called from a library within the provided file.  When I first started coding this button, I added a simple alert() to the initial function call so I could quickly validate the buttons functionality, deploy it and move on to the rest of the implementation.

Capture

There are a host of other options in creating a button related to display rules and Hide actions which can make your implementation that much more dynamic.

What I really like about the Ribbon Workbench is that the customizations are deployed directly to your solution without having to deploy the workbench solution between environments.

No external Dependencies = awesome development!

User Interaction

In my scenario, the button that I created was calling an action where the results were passed back to my calling function – for better or for worse.

Adding to my integration, I sent a notification back to the client when the action had completed.  If there was an error, the error was sent to the client.

For an Informative warning this looked like.

Xrm.Page.ui.setFormNotification("Authorization successfully sent.", "INFORMATION");

And in the case of an error.

 function (e) {
 // Error
 console.log("Workflow Err: " + e);
Xrm.Page.ui.setFormNotification("Could not Authorize, Error: " + e, "ERROR");
 }

When both solutions are thrown together, a great integration story for facilitating calls to a custom service, action or workflow and updating users on the status of those calls when completed.

Raising The Bug Bar

In our quest to find the latest, greatest and bestest methodologies out there to ship great software we often overlook the simplest of implementations to get a project going – The Bug Bar.

As much as I wish this was an actual bar a la Bugs, it’s not.

bugs.jpg

The Bug Bar is a simple tool used to keep your team’s head above water when shipping copious amounts of software against an unpredictable schedule.

How it Works

Before each iteration set a maximum number of bugs that can be reported that cannot be triaged into a subsequent iteration based on their priority and severity to the project.

There is no discerning between bugs raised by Developers, QA, End Users or your mother – they are all created and treated as equal.

When that number is hit during the iteration, all feature and task development work is halted until the bar drops down to an acceptable level to then return to feature and task development.

What it Does

Ensures the team is focused on not rushing task and feature development by introducing bugs in the software that were previously not there but aren’t being worked on in the current iteration.

Ensures that the entire team (for business to project to development) are on the same page with this level of importance and know how to react accordingly when this happens.

Ensures your Project Manager is monitoring the bug lists and actively triaging what does and doesn’t apply (taking this load off of Developers).

Sets the expectation that the content is greater than the date.

It’s not a complicated concept, it’s downright simple, but sometimes that is where you need to start to see a change in the delivery of your software.

Disabling Quick Create

I ran into an issue the other day where I needed to turn off the usage of Quick Create forms and ensure that the standard forms would always be used for form creation.

The option to do this per entity is relatively simple – Navigate to your entity (via the solution) and uncheck the following entry.

ActivityPointerFail

Not a problem to do per entity, but it would be nice if there was a bulk, non-coding writing way to disable this functionality across all of your entities.  This is a good example of where these features can then be implemented across the board ensuring a consistent user experience.

Failed to Import Solution Error

I encountered a rather odd error the other day when I was having to do schema changes between organizations that involved a lot of importing and exporting when at one point I could not import the solution into one of my target orgs anymore.

After some digging through the Dynamics logs, the problem became very clear.

I had a field that had been incorrectly typed, so in my source org, I deleted it and recreated it.  When I proceeded to import the solution updates into my target org I could not perform the import because the field already existed but in an incompatible field type.

Specifically, doing some searching through very verbose CRM log file yielded the following entry.

Attribute new_legacyid is a Integer, but a String type was specified.

To get around this issue, I removed and deleted the field new_legacyid from my target org and then performed the import again, which then went smoothly from there.

 

Updating the State of a Record in Dynamics

Had some head banging to do this past week when I wanted to update the state of a record in Dynamics.  For some reason, this has always been an indirect path to accomplishing a simple task.

This article applies only to Dynamics 2015/2016 and below.  In Dynamics365, this method is being deprecated in place of the Update method (YES)!

Before you code anything, there are two references you are going to need in order to access the correct object.

Microsoft.Crm.Sdk.Proxy

Microsoft.Xrm.Sdk

Now that you have those two references you can now leverage the SetStateRequest message to submit your state change (after your entity was created).

 SetStateRequest request = new SetStateRequest();
 request.EntityMoniker = new EntityReference("your_entity_name", EntityId);
 request.State = new OptionSetValue(1);
 request.Status = new OptionSetValue(2);
 
 svc.Execute(request);

In the above, EntityId is the primary id (guid) of the record that was created.  The 1 and 2 are values represent the statecode and statusreasons fields in your system, while statecode will generally be the same (Active = 0, InActive = 1), statusreason can be wildly different.

An informative list of status codes are available here.