Creating a custom Status for your (custom) entity

It’s been always a mystery to me why we’re not able to change the status field on an entity. We just get to change the status reason field, but sometimes you just want some more. Microsoft knows it, cause they use multiple status fields on for instance the Lead and Opportunity entity.

Let face it: most of the time it’s just fine to have Activate and Inactive as statuses on your entity. (Now that we’re talking about statuses… Isn’t it just weird that Active has the value 0 and Inactive the value 1??!) But there are those situations that you just need more. For instance one of my customers log their medical consults in an entity. In this case it would have been great to have Active, Processed and Invoiced as statuses. And you know what: it’s possible!

Now before you get too excited about this I need to temper your enthusiasm a bit. Although it can be done, it’s unsupported customization. When you read my solution and you read this article, you’ll understand why it’s unsupported. Since it’s unsupported, I would strongly advice you to do this only for custom entities and not for oob entites. So far for the disclaimer 🙂

In order to add or change the statuses you need to change the customization xml file. Now let’s go through the steps. (I expect you to have some experience with customizing Dynamics 365 CE. If not, please contact your Microsoft partner to execute these steps.)

Create the solution and get the right file

Create a temporary solution with just what you need. In this case, just add the status and status reason fields from the entity you wish to change. Although you just want to change the status field, you’ll also need the status reason field. Later on it’ll come clear why that is needed.
Export the solution and open the zip file. Now get one file out – the customization.xml file – and store it somewhere to edit.

Edit the customization xml

Now comes the editing of the file. Please be careful here, cause you might break something here.
In the file, locate this part

<states>
  <state value="0" defaultstatus="1" invariantname="Active">
    <labels>
      <label description="Active" languagecode="1033" />
    </labels>
  </state>
  <state value="1" defaultstatus="2" invariantname="Inactive">
    <labels>
      <label description="Inactive" languagecode="1033" />
    </labels>
  </state>              
</states>

As you can see, both default statuses (Active and Inactive) are there. Notice the defaultstatus tag that is in there. This is important and indicates the default status reason for that status. Since we don’t have a status reason for it yet, we will just fill in a random number now that we’ll use later to create the status reason with.

To create the new status just copy everything between a <state> and </state> tag and change the value, defaultstatus, invariantname and desciption. It should look like this. In this example I use Invoiced with vaue 10000. I would always use a high number as you never know what Microsoft comes up with in the future.

<states>
  <state value="0" defaultstatus="1" invariantname="Active">
    <labels>
      <label description="Active" languagecode="1033" />
    </labels>
  </state>
  <state value="1" defaultstatus="2" invariantname="Inactive">
    <labels>
      <label description="Inactive" languagecode="1033" />
    </labels>
  </state>
  <state value="10000" defaultstatus="20000" invariantname="Invoiced">
    <labels>
      <label description="Invoiced" languagecode="1033" />
    </labels>
  </state>                  
</states>

Now we need to do the same for the status reason field. Please keep in mind the value for the status reason should be equal to the defaultstatus value that we’ve used before. The same goes for the state.

<statuses>
  <status value="1" state="0">
    <labels>
      <label description="Active" languagecode="1033" />
    </labels>
  </status>
  <status value="2" state="1">
    <labels>
      <label description="Inactive" languagecode="1033" />
    </labels>
  </status>                    
  <status value="20000" state="10000">
    <labels>
      <label description="Invoiced" languagecode="1033" />
    </labels>                    
  </status>
</statuses>

Import the file and you’re done! 🙂

Now that you’ve changed the cusomization xml file you should put the customization xml file back into the solution zip. Notice that it overwrites the existing customization xml file. Import the solution zip back into your environment and you should have the new status.

Things to take into consideration

Again, this customization is not supported. Always be careful with these unsupported customization and question yourself if you can’t do it any other way.

Since it’s unsupported, the user interface doesn’t take your new status into account. There is no out of the box option to set a record to your new status. You can use workflow or you’ll have to create a button on the command bar to set your status.

Last but not least: as for as I could see, when a record is in the new status, its forms are always in read-only state. The Active status is the only status where you can edit the data on the form.

Nested groups not supported in Dynamics 365 CE

So at my current CE project, we want to work with guest user access in CE. This company uses an external company to process incoming e-mail and phone calls. They would like the users from the external company to directly login to their CE instance and do their jobs. This can be done perfectly by the new guest user feature in CE.

Now from a maintenance perspective in Azure Active Directory, you’d like these specific guest users to be in a separate group, so you have them grouped together and can maintain them all together. That would mean you have two security groups with users that need to access the same CE instance. Unfortunately, you can only have one security group setup for accessing one CE instance… :-(.

But wait, what about nested security groups! I created a third security group and made two other security groups member of the third. But when I added the third security group to the CE instance, nobody could login anymore… There was the gap: nested security groups are simply not supported. So we ended up with one security group that had all users in it. Not particularly Azure Active Directory best practice, but it worked 🙂

Also want support for multiple or nested security groups? Good! Vote for my idea here.

Activation Failed status on Data Export Profile

I’ve setup the Dynamics 365 Data Export Service numerous of times and I’ve made a lot of companies happy with this service. Having your Dynamics 365 CE data in a separate database has advantages for reporting, but also for data quality checks.

In my current project, we’ve done a data migration from a previous custom application to Dynamics 365 CE. This customer had a huge amount of data and we ended up with a Dynamics 365 CE database of 150 GB of data. After the migration we wanted to do some checks if all data had been migrated correctly. We used the Data Export Service to make that possible.

When we created the Data Export Profile we simply checked the ‘Select all’ option, since we wanted to do quality checks on ‘all’ data in the database.

Unfortunately, we got an error immediately when we finished the wizard!

After some digging, we found the issue. There are some entities in Dynamics 365 CE that are available for selection in the entity list (since they are track change enabled) but seem to break the Data Export Profile. The entities I found so far are:

  • mobileofflineprofile
  • mobileofflineprofileitem
  • mobileofflineprofileitemassociation
  • offlinecommanddefinition

Simply uncheck these entities and you are good to go!

WebApi batch request

The WebApi in Dynamics CRM has the option to send batch requests. This reduces the number of calls from client to server and when e.g. you need to delete a lot of records from JavaScript it saves time processing these deletes.

Unfortunately, creating a batch request is not as straight forward as doing a POST call for example. The MSDN documentation is a good starting point, but then I still had some trouble making it work. I’ve created a question on stackoverflow and the Dynamics Community. As I needed the functionality I kept trying different options and reading the documentation and I finally figured it out.

It’s very important that you build the content in the batch request as documented with MSDN. Also note that when you do a delete batch request you still need to send an empty object. With a single delete call to the api you don’t have to explicitly do this. Another things that’s a bit hard creating a batch request, the errors that are returned are not existent. You just get an empty result and you have to figure out yourself what you have done wrong.

This is the request if you’re using jQuery to do the call.

$.ajax(
{
    method: 'POST',
    url: 'http://crm/api/data/v8.0/$batch',
    headers: {
        'Content-Type': 'multipart/mixed;boundary=batch_' + batchId,
        'Accept': 'application/json'
    },
    data: payload
});

And here’s the way to build the payload:

var data = [];
data.push('--batch_123456');
data.push('Content-Type: multipart/mixed;boundary=changeset_BBB456');
data.push('');
data.push('--changeset_BBB456');
data.push('Content-Type:application/http');
data.push('Content-Transfer-Encoding:binary');
data.push('Content-ID:1');
data.push('');
data.push('POST http://tenanturl/api/data/v8.0/accounts HTTP/1.1');
data.push('Content-Type:application/json;type=entry');
data.push('');
data.push('{ "name": "batch acount 2"}');
data.push('--changeset_BBB456');
data.push('Content-Type:application/http');
data.push('Content-Transfer-Encoding:binary');
data.push('Content-ID:1');
data.push('');
data.push('DELETE http://tenanturl/api/data/v8.1/accounts(52eb1677-427b-e611-80bb-0050568a6c2d) HTTP/1.1');
data.push('Content-Type:application/json;type=entry');
data.push('');
data.push('{}');
data.push('--changeset_BBB456--');
data.push('--batch_123456--');

var payload = data.join('\r\n'); 

Easy contact form to CRM lead using Microsoft Flow

Many companies are looking for an easy solution to process a contact form on their website to a lead in CRM. In this post I’ll provide an easy, self service solution that requires no code.

Tools

To build this solution we are assuming you use the following tools.

  • You have Dynamics 365 for Customer Engagement
  • Microsoft Flow is enabled in your Office 365 tenant
  • You are ok with using Cognitoform or any other form tool or custom code that can post the form data to an url
  • You already use WordPress and Contact Form 7

I’ll be using a generic approach where you parse the json data from a webhook call. The tool above also has a built in connector to Microsoft Flow. That would even be a better option, but not all platforms support Flow. This approach is very easy to implement for a developer building your website.

Setup

The first thing we need to create is the basic Microsoft Flow. Go to Microsoft Flow and log in with your Office 365 credentials. Create a new flow and start with a blank canvas. The first step is adding a trigger. The trigger you are looking for is the Request trigger. Select it and don’t fill out anything just yet. Next, add the Dynamics 365 connector and configure it to create a lead in your CRM instance. For now just use some dummy values. Save your flow and notice that you’ll get a request url in the Request trigger. Copy that so we can use it in the Cognitoform setup.

It’s pretty easy to setup a test account with Cognitoformand and create your first form. It took me less than 5 minutes. After you are done configuring your fields, you want to go to the submission settings on the bottom of the page. Add the Flow url in the “Post Json data to a website”:


Test your form and return to your flow and you’ll likely see one run has failed. That’s ok for now. Click this failed run and look for the request body of the trigger. Copy that:

Edit your flow and click the Request trigger. Click “Use sample payload to generate schema” and paste in the json from the previous step. Now you have defined the schema from the request and you can use those schema values to create the lead. Click the “Create record” step and use the defined values form the previous step to enter the values for your CRM fields.

Now you’re all setup. Fill out a form a see that a lead is created in CRM.

New: the Scribe Online Toolbox

Six years ago, I started working with Scribe and since then I use some Scribe component in almost every project I do. With Scribe Online as my no. 1 integration platform I’ve been able to take most of my integration requirements to a success.

When you work with Scribe Online a lot, you notice some features are missing. Features that don’t affect the integration itself, but that make your life as a Consultant or Developer easier. Well here is www.scribeonlinetoolbox.com. Together we should make life easier!

Let’s make a wishlist:

  • Bulk enable/disable Solutions – one of the connecting application goes into acquaintance mode. Your Solution tries to connect every 5 minutes, but since the application is down, email start to run. Would it be easy to just enable or disable a couple Solutions with one click?
  • Bulk enable/disable Maps – exactly the same as above, but now for Maps 🙂
  • Easy transfer Maps from one Solution or Org to another – most customers have separate Orgs for their dev, test, acceptance and production. It would be great to have the possibility to just transfer a Map from one Org to another without the need to download and upload the json file, modifying the name, validating etc.
  • Documentation in one click – a nice presented Word file with your block-structure and mappings in place? (ps. I know about the Google Docs tool, but let’s face it… it’s Google Docs….)

I’m sure you can think of more tools we might need ;-). For now, I started with the first one and will continue to work on the other tools. Please let me know if you have any ideas or what you think of the Scribe Online Toolbox :-).


Hidden feature: OpenAPI Spec for Scribe Online Request/Reply Maps

Since Scribe launched the Request/Reply functionality, it’s hard for me to think of any project where it couldn’t be used. For those of you who don’t have any idea what I’m talking about: Scribe Online Request/Reply offers the capability to create you own WebApi without any coding. With just a few clicks, you are able to get a url and define any (complex) logic behind. If you want to read more on Scribe Online Request/Reply, check out this blog post by Paul Varley.

OpenAPI Specification / Swagger

With the ability to create and customize your own WebApi rapidly, the need for a specification about your API grows. Especially when you provide the API to customers or partners. Lucky for us, someone thought of this. The world of API’s has embraced an open standard for API specifications. This standard – formerly know as Swagger – is called OpenAPI Specification. You can read all about it at https://swagger.io/.

How to get a specification on my Request/Reply?

This is where the fun part starts, cause it’s so-so-simple! When you create your Request/Reply, you get the endpoint url. Let’s say it’s like this:
https://endpoint.scribesoft.com/v1/orgs/123456/requests/1234?accesstoken=XYZ

Now in order to get the OpenAPI Specification, all you need to do is to add ‘/api-docs’ at the end of your url, right before the parameter! It’ll be like this:
https://endpoint.scribesoft.com/v1/orgs/123456/requests/1234/api-docs?accesstoken=XYZ

Now dump the url in your browser and you’ll get the OpenAPI Specification you want. In a next blog, I’ll tell you all about how you can use this together with Microsoft Flow.

Creating an activity through the CRM WebApi

Recentely I had to create a phonecall activity through the WebApi in Dynamics 365 CRM. As most WebApi calls are pretty straight forward, I didn’t think much of this task, although I haven’t done this before. As I knew activities are special in CRM I looked around to see examples and couldn’t find any good ones. Therefore I’m writing this post, to make sure I have an example on hand when I need one.

Endpoint

To create an activity you use the relevant endpoint. These are /api/data/v9.0/phonecalls, /api/data/v9.0/emails, ect. Maybe there’s an option to use the generic endpoint, but I haven’t tested this.

Json message

For a phonecall the Json message could look like this

{
    "description" : "Lorem ipsem",
    "directioncode" : true,
    "leftvoicemail": false,
    "regardingobjectid_account@odata.bind" : "/accounts(EA82D93B-CFD9-E711-812D-E0071B6C2F31)",
    "subject" : "lorem ipsem", 
    "phonecall_activity_parties" : [
        {
            "partyid_systemuser@odata.bind" : "/systemusers(5549B1A7-A7CD-4047-84CC-64BA1FF4756F)",
            "participationtypemask" : 1
        },
        {
            "partyid_contact@odata.bind" : "/contacts(4F2D083E-D3D8-E711-812C-E0071B6C2F31)",
            "participationtypemask" : 2
        }]
}

Validate your IBAN bank numbers

During multiple implementations of Dynamics 365 for Customer Engagement or Dynamics 365 Business Central, we get the question weather it’s possible to validate the entered IBAN bank account numbers and generate the BIC / Swift code. Especially when companies use Direct Debit as a payment method, you want to make sure the IBAN is correct.

I’ve created a simple REST service based on Azure Functions to validate the entered IBAN bank account number and provide the name of the bank and the BIC / Swift code.

How it works

Let’s start with testing this in your browser. For now we want to check if an IBAN is valid. We can do that by combining the url below with and IBAN (for instance NL63TRIO0379272687).
URL: https://iban-validation.dynamics365blog.nl/api/IBANCheck?iban=NL63TRIO0379272687
You’ll get back all the information you need:

{
    "valid": true,
    "messages": null,
    "iban": "NL63TRIO0379272687",
    "bankData": {
        "bankName": "TRIODOS BANK N.V",
        "bic": "TRIONL2U"
    }
}

Currently for Dutch and Belgian IBAN, but more coming!

Currently, the REST service only Dutch and Belgian IBAN bank numbers. If you want to have other countries supported, please provide me a url in de comments where I can find a list of banks and their local bank identifiers. If you’ve proved the url I will setup the new country as soon as possible.

Manage your service calendar resources in Dynamics 365 CE

I know we shouldn’t use the good-old Dynamics CRM Service Calendar anymore. But let’s be honest: it still works for a lot of companies! I have multiple customers still using the old service calendar. Wanting to move to Universal Resource Scheduling, but waiting for some extra features to come.

With the use of the service calendar, I always find it annoying that all users will be on there. Most of the time you just need the users that need planning and not all (especially not your service users or administrative users). So I tried to figure out if there is a way to get rid of some users on the service calendar.

So the data model works as this: the service calendar shows both users and equipment. To show both of these in one view, MS created an extra entity: resources. When a user or an equipment record is created in the system, an equivalent record is created in the resources entity. The status of the user or equipment record is being copied to the resource record. When the user gets disabled, the equivalent resource record will be disabled as well. The same goes for equipment records.

But what if you have a user that you need to be enabled, but you don’t want it on the service calendar? This could be for service users of administrative users, but maybe also ‘normal’ users. Unfortunately there is no way to disable/inactivate the resource record via the user interface. The only way is to do it via the API. You can do this grammatically or you could use Flow or a tool like Scribe to do this.

Enjoy!