Microsoft the ISV

Microsoft published their new Shopify connector today. It’s great to see them invest resources into what is hopefully the gold standard of integrating with these external services. However, I have serious doubts about whether this is such a good idea.

ISV Partner Channel

In the runup to having BC in the cloud, the story was that the partner channel should refocus their efforts into becoming ISV’s. Rather than one-time bespoke systems for individual customers, they want the partner channel to create extensions that could be used by the masses.

This was (is?) a logical continuation of their story of verticalization that we had heard throughout the past two decades. In itself nothing that I don’t agree with. I too think that having re-usable extensions in a marketplace is a solid way to go. Microsoft’s argument was that they need to focus on the base product, a core set of functionalities. The partner channel would then be free to add functionality, to extend the base product.

There’s Just a Tiny Thing…

One thing that caught my ear was a statement that said that Microsoft does not want to provide specific, industry focused expertise. They said they have no interest to build integrations with external systems. Rather than having Microsoft provide integrations or other specialized functionalities, they would leave this up to the partner channel. There could be an ACME Rockets integration created and supported by an ISV, or even by ACME themselves.

Great soundbite showing great potential, and it sold well. Many partners listened to Microsoft and started creating lists of functionalities that they have know-how for. Many VARs dove right into their inventory of “add-ons” with the intent to turn those around into the next AppSource apps.

I know personally of three separate partners that have invested a lot of time and money into developing Shopify integrations. All three of those partners are LIVID with Microsoft today. The promise was that Microsoft would stay out of this type of functionality, and today’s release is one of an unknown number of apps that we will see come out of Microsoft.

Besides the fact that Microsoft is now on the hook for maintaining this app, they have effectively cut off the potential from the ISV channel. Their work in progress as essentially turned into a big fat tax write-off.

What Next?

Two out of those three partners had already been looking at alternatives to their NAV/BC practice, and I can’t say that I blame them. Licenses are no longer capital investments. Margins are going down with lower subscription fees, so you can no longer afford to focus on smaller businesses as clients. Having to go through a primary CSP means that you have to share what little margin remains. The stack has become much more complex, so you have to hire experts for everything.

One of the last things that are left is to develop your own IP and publish on AppSource. Would you decide to invest in new products if there is a real chance that Microsoft is working on the same thing?

Personally, I think Microsoft is making a huge mistake by creating this type of app. I am not sure if they are capable of taking on the support, and that they will be maintained properly. I am also doubtful about the cooling effect this will have on the partner channel’s willingness to invest in new products.

Most important though is that I am just flabbergasted that they prioritized something like this, when there are SO MANY things still left to improve in the base product.

As I am writing this I am struggling to find a good way to finish this post, I’m clearly not done thinking about this. Let me know in the comments what you think.

Dynamic Enums

Although enums are static lists of values, there is a way to restrict which values can be used. With this post I will show you how to do that, and how you can dynamically set up how this happens.

Didn’t Think it was Possible

I didn’t think dynamic enums were possible but I asked the question on Twitter anyway. The golden tip was a page property called ‘ValuesAllowed’. As I was figuring out how to use this property I thought I’d write this blog post. When I returned to Twitter to post my findings, there were two more links to some other people’s articles in the replies. I’ve since removed much of the details from this post, since they are essentially the same. Go and follow the links in the Tweet replies to read those details.

Both replies cover an essentially hard coded way to restrict option values. I want to take this one step further, where we provide a setup field that is used to manage the choices that you see. Now… I have to say I do NOT like using a static list of options for this purpose. We are still looking at a static list of values, and we are hardcoding what is visible. In my real-world scenario we had to put something in place quickly, and this was indeed a very quick ‘fix’.

Scenario

My actual scenario involved a rather controversial topic, so let’s use a silly scenario instead. We add a field to the Customer table called ‘Dessert Choice’, with an enum type that has 4 values: <blank>, Icecream, Cookies, and ‘Choice Declined’. You need an enum object, a table extension with a field based on the enum, and a page extension to add the field to the Customer Card. Let’s say you want to restrict the ‘Choice Declined’ option. Easy peasy, lemon squeezy, you add a ‘ValuesAllowed’ property to the field on the page extension, and you specify the values that you do want to allow.

In my real-world scenario, my client needed a way to restrict the available options for one company, and provide all of them in others. What we ended up doing was add a toggle to a setup table to turn this restriction on or off.

Show Me The Code

As per usual I was writing and writing, using SO MANY words to describe the situation, and decided to just give you the page extension itself, assuming that you can figure out the fields that I am using.

pageextension 60000 CustomerCardDnStr extends "Customer Card"
{
    layout
    {
        addafter(Name)
        {
            field(DessertChoice; Rec.DessertChoice)
            {
                ApplicationArea = All;
                ToolTip = 'Specifies...';
                Visible = AllVisible;
            }
            field(RestrictedDessertChoice; Rec.DessertChoice)
            {
                ApplicationArea = All;
                ToolTip = 'Specifies...';
                ValuesAllowed = Blank, Icecream, Cookies;
                Visible = (not AllVisible);
            }
        }
    }

    var
        MySetup: Record MySetupDnStr;
        AllVisible: Boolean;

    trigger OnOpenPage()
    begin
        MySetup.GetRecordOnce();
        AllVisible := MySetup.AllowDecline;
    end;
}

Basically you create multiple controls in the page extension for the same field, and you toggle visibility based on a field in a setup table. You could even do this at a record level in a list, by using an InDataSet variable, and putting the code in the OnAfterGetCurrRecord trigger. Again, I’m thinking this should have been done with a table with actual functionality, but this way uses very little code and we had to put something in very quickly.

That’s it, nothing fancy. Not very clever, but useful in my client’s scenario.