Category Archives: Dynamics NAV

AL Extensions – File Naming and Organizing

This is a blog that I wanted to write for quite a while, but it’s only until last week or so that I think I’ve found what I like to call, a “best practice” or if you will, a “Design Pattern”.

What is this all about? With the move from C/AL to Visual Studio Code we also moved to file based instead of stored in database.

This means we also have to give these files a name and we have the option to organise the files into folders, or subdirectories if you are a born-in-dos generation.

If you follow the Microsoft guidelines and/or use the tooling from Waldo your extension your extension will probably look something like this:

Although this works perfectly there are a few issues with this that I don’t like. I’ll try to explain myself.

Object ID’s

The Object ID is still there. Not perse a big problem but in the cloud they don’t mean anything anymore except making the object Unique. In the past, we as developers tried to use object ID’s in a smart way, like make sure that table & page have the same ID, or make sure that Header and Line tables have adjacent ID’s so Object Designer in C/Side would show them nicely grouped.

In most projects as well as in Microsoft’s BaseApp this is no longer true and possible. We have too much legacy to trust sorting and grouping objects by ID.

Prefixes

If you prefixed your objects in C/Side and run the conversion your filenames look something like this.

To me this looks like a horrible waste of the first 15 or so characters of your filename. I tried it for a while and it’s very hard to work with.

Abbreviations

For reasons of legacy object names in AL can only have 30 characters. On top of this you’ll loose 3 or 4 on the TLA you need to mandatory put in my Microsoft. This often leads to horrible object names which are then converted to your file name

Lack of Intent

If all of your projects have the same object tree it does not make it very clear what kind of extension you are looking at. By opening the project we can only recognise it as an AL project but we cannot see what it does.

I can hear you say, so what? What do you suggest we do Mark?

BaseApp

When I opened the BaseApp in AL I got the first Aha moment on how to solve this puzzle. To my surprise Microsoft was not following their own guidelines.

It would not be the first time they don’t follow their own guidelines and at first it pissed my off a bit. But only untiil the beauty of this naming pattern struck me just like that.

With these naming guidelines you can automagically see what belongs together regardless of the Object ID and Object Type

Old Naming Conventions

For those of you who remember the old Solution Developer materials will also know that there are strickt naming guidelines. Like the Table Name is singular, the Page Name is Plural. If you have a List and a Card you name them like that etc, etc, etc.

If you were religious about these rules and follow this pattern your project suddenly makes much more sense to look at.

Subfolders

So I hear you say, what about subfolders? The BaseApp has over 6000 files and this naming does not make it easy to work with if everything is in one root folder.

The logical answer here is to apply common sense. Group your objects together if they belong together.

Clear Intent

This also gives your project a clear intent. I can see by looking at the folder structure that this is a report pack with Labels, Sales Taks reports, Financial reports, and so on, and so on.

Remove Abbreviations

If you remove the abbreviations and then look at for example a Journal the pure beauty of this way of working with files becomes as clear as sunshine on a cloudy day.

See how nice the Batch, template and register are grouped together and it’s very easy to find the file you need.

One can debate if in this specific case the word “Example” is overkill, but if you think for a moment it would say “Item” I’m sure to think you agree with me.

Call to action

To me this is another indication of how smart one of the old Navision rules were and it looks to me that Navision was born in the cloud back in the late 1980ies. They just had not invented the cloud yet.

Use your brain, think out of the box and be surprised.

Managing DotNET Dependencies on AppSource for Business Central

When you try to convert existing C/Side objects to AL the first attempts are typically done while scoping OnPrem. This gives an overview of the errors to be fixed w.o things like DotNET.

In this phase you typically switch between C/Side and Visual Studio Code all the time fixing the errors one-by-one and reconverting.

Once the errors are fixed the software can be tested and deployed using either Docker or a local install.

This is a very safe way of ensuring there is a migration path for your existing customers what is not overly complex and thus affordable from a TCO perspective.

The next step is moving to AppSource and this is where you need to remove all the DotNET dependencies.

The biggest issue with DotNET is that it’s often used in interfaces and most partners that I’ve worked with put every interface they ever did in their C/Side toolbox just in case you ever need it again.

Chances are you may never need many or most of them, but how do you determine that? And where to start?

Decouple!

If you can somehow decouple your business logic from your DotNET dependencies you create a Core solution, and each interface can be a dependent extension.

These depedent extensions will most often be per-tenant extensions. You don’t want to go through the whole AppSource validation for interfaces you only need almost never.

Example

Let’s look at a simple real life example I did today. It’s an interface that reads the ferry sailing times from TT-Line and offers the option to book one.

Off course decoupling is smart here in the first place since you may also want to interface with other ferry companies but that’s not what we’re looking at now. In the example I have the C/AL code and the DotNET code is on one codeunit and it needs to be decoupled.

The Function GetTimeTable is called from the application somewhere. If I remove this codeunit from my extension I get errors.

Step 1 – Copy the codeunit using File-Save As and call it <<Name>> Impl.

This separates the link between your application and the code making the orriginal codeunit a Facade and the new codeunit the Implementation.

Microsoft also does this in the new System Application

Step 2 – Remove All Code from the Facade and change the functions in Event Publishers

This is different from what Microsoft does in System Application. In our case we don’t want a strong contract between the Facade and the Implementation.

Step 3 – Change the functions in the Implementation to event subscribers

Just enter the property window and add the correct properties. Trust me, it works.

Step 4 – Mark the decoupled codeunit in the Version List

When 100% conversion between C/Side and AL is the goal (and it should be the goal) you can use the Version List to mark your objects as part of Core, or as part of a dependent Extension.

Step 5 – Determine what’s next

Now you can ship to AppSource but you’ll have a function that does nothing. You need to rewrite this code to make it work.

Most often there are two scenario’s.

A:> Make use of the new HTTP type variables in AL

B:> Create an Azure Function

Both are valid options and the correct choice depends more on questions like flexibility and language of preference.

NEVER, EVER put interfaces in your Base AppSource solution unless you trust the contract of the API with your life!

Interfaces change all the time. Put them in a Per-Tenant extension or in an Azure Function because these can very easily be changed, debugged, etc.

Monolith ≠ NoOfObjects | Breaking up your extension

If you have IP for Microsoft Dynamics NAV in C/Side your are either in the process of moving it to AL and Business Central or you are busy finding a buyer for your company. Both seem to be very valid options these days.

When you talk to the engineers who are busy executing this task the number one question on their mind, once they got their stuff decoupled from BassApp, is how to break up their extension in multiple apps.

Breaking up as a goal

I was one of the first to blog about the Business Central BaseApp being a monolith application and I have a strong opinion on how to solve it. The new Enum and Interface is the key to solving that puzzle. I’ll get back to that later in this blog.

I get much inspiration for my opinion from following Uncle Bob Martin and reflecting his idea’s to our framework.

This tweet of him caught my attention.

This tweet circled be back to my opinion that just because something was built in C/Side does not make it a monolith. Even if it has many objects.

The ForNAV Report Pack we publish on AppSource has a few hundred files and we’ve divided them into three Apps; Core, Report Pack and Report Pack Test.

Technically we could have taken it even further. Like for example the MICR Check Report for the North American market could have been it’s own App.

Quickly after breaking up our App we learned that working in different Apps is very hard, especially in a small team and my colleague Jacob came up with the idea to make them back into one App during development and then “PowerShell” them into seperate Apps before we publish. Again, more for another blog.

When I did the challenge from Michael Megel yesterday I took decoupling into the extreme with making the al.address pattern depend on the al.masterdata.person and the al.entitystate depend on al.masterdata.product.

Truth is that you can take decoupling and dependencies into the extreme. You’ll end up in a dependency hell.

How and When to Break Up

This may sounds strange, but this decision is more in the hands of your marketing department than in your development team.

Rule #1 – If you want to sell it seperately it needs to be a seperate App.

Cannot make that one simpler than it is.

Rule #2 – Create your own System App with reusable components

Microsoft experimented with making micro extensions, however they suffered from the same issues we had in terms of manageability. You can still make each module have it’s own folder and even check if it compiles separately by giving each module it’s own app.json file.

Rule #3 – Add Reusable code to Microsoft’s System App

This should be Rule #1 actually. As Bugsy said in the NAVTechDays keynote you can submit modules to the Microsoft System App and have everyone share the same code

Rule #4 – Keep it together if it belongs together

Microsofts BaseApp has over 6000 objects and the compiler chews through it with relative ease. It’s bigger than it could be because we lack some features in our language to make it smaller. This results in a lot of cloning of both code and metadata.

If you have a vertical solution you should not be scared if you end up with a core module that has several hundred objects of maybe even slightly more than one thousand.

The compiler wil manage and you can have multiple developers work on features using git with branches.

Rule #5 – Move Interfaces into dependent apps

Most partners I worked with in moving to AL had an endless number of interfaces in their solution. Basically everything they cooked over the years for projects was added to the solution in case they ever need it again.

Move this into small Apps with a clear, reusable interface. Leverage the power of Event Publishers with using an Argument table as a strong contract.

This way you only need to install them at implementations where you really need them.

What makes BaseApp a Monolith?

If you can make decoupled code in C/Side, then why is the BaseApp so hard to work with?

It seems that optionfields that make Business Central so flexible are the achilles’ heel which is why Microsoft is working on the Enum and Interfaces.

Just the Enum was not enough, this would leave the case statement as a problem.

So that’s it?

No, not quite, but it would be a major step in breaking up the BaseApp without breaking changes. Another feature we need which may prove itself even harder to implement is extendable flowfields.

Proof of Concept?

If you look at how Business Central was built we can probably break it up the same we it grew. Move modules that were added later into dependent extensions.

Microsoft asked me to do a proof of concept but I doubt if I will have time to do that. We meet in January and breaking up BaseApp is on top of the agenda.

Maybe a few members of the community can work on this together? Many hands make light work.

The goal would be to move a module like Fixed Asset, Service Management or Production to a dependant app without breaking changes (or keep it within certain limits).

Who is up for it?

NAVTechDays – It’s a peoples event…

It’s the weekend after NAVTechDays and I rested from a busy week. Two days of pre-conference training and two days of talking at (a lot of) people mostly at the ForNAV booth but also at the booth of Meta UI, Continia, SQL Perform, Anveo, Prism and AL Ops.

Design Patterns, once again

Teaching the Design Patterns for AL the first time was fun, challenging and exhausting. It was fun because I got to talk about my passion once again, clean code and design patterns. Challenging because it was the first time on AL and my attendees almost all were experienced with having apps on AppSource and PerTenant apps. It was exhausting because I had no idea what to prepare for and the group was very interactive.

Once again I felt I learned more than the students combined. I know that our community is ready for the next step in AL. We finished converting from C/Side and we’re ready to move on. Some of us at least.

One of my attendees, you may know him, Michael Megel encouraged me to think out of the box once again and take the patterns to the next level of abstraction.

I’ll blog about this more in the following weeks but you can take a sneak preview at https://github.com/al-design-patterns.

With C/Side the patterns were left behind with Microsoft on their old wiki. I talked at NAVTechDays with Bugsy to see if they can be carried foreward to AL and Visual Studio Code too. To be continued.

Although I don’t have the ambition I had a few years back I do hope to teach a bit more next period. I am traveling to Denmark next week to teach PrintVis and I applied to teach the class at Days of Knowledge in Denmark.

NAVTechDays

I felt the general atmosphere at NAVTechDays was very positive. The most positive I have seen in a long time.

At the ForNAV booth I have only done demo’s of our AppSource solution. Nobody is remotely interested in the old world which is great.

Where last year most attendees had no clue of the problem we’re trying to solve they now were super enthousiastic of our offering. I guess you first have to try RDLC with AL to appreciate the alternative. ;-).

This seems to be even more true for the new Meta UI product from Global Mediator. It’s now roughly 15 months ago that we locked up two insanely smart JavaScript/Angular experts in an office with no outside windows. I gave them an API endpoint and the question to use that MetaData to build an improved Grid control. The rest is history and the product, a result of more than 10 manyears, was presented at NAVTechDays last week.

I was so proud to see one of these JavaScript experts, the architect of the solution, giving demo’s of the product as if he lived his whole life in Business Central and to hear people say things like “where did this come from all of the sudden”, and “this is by far the best thing I’ve seen this year at NAVTechDays”.

It proves that to be successful with Business Central you need to step outside of your comfort zone and work with people who are smart in technology that can be combined with AL very easily.

Where Directions are to give a roadmap to a company, NAVTechDays is to give inspiration to developers.

The sponsors of NAVTechDays are all but one (I think) companies that offer tools. Different from Directions where there are more vertical solution ISV’s using the oportunity to talk at their international partners.

I hope that NAVTechDays and Directions can co-exist side by side for many years to come although it may be time to start calling it BCTechDays.

WARNING – The Data Upgrade Elephant

Last Thursday I was at the QBShare event in Veghel, Holland. I’ve been attending these events ever since I joined ForNAV a few years back and since the audience is a bit different from my normal events (CEO vs. Developers) it took me a while to get to know people.

No matter who you talk to at these events, all that they have on their minds is moving their IP to Business Central and most are in the middle of that project, some with my help.

This is all great and it’s cool to see peoples growing entousiasm but at this event I raised a question that for me is very obvious but to my surprise it was not for others.

The reason for my question was this slide in the presentation from William van Voorthuijsen.

Once partners are ready putting their IP on AppSource the next step is onboarding customers. Naturally you will start with customers who are as current as possible.

These customers will want to migrate data, including transactions, to Business Central and in order to do that they first have to migrate their OnPrem NAV to BC15 with a more-of-less matching schema.

WHAAT???

I hope that after following my blog nobody believes in the no-more-upgrade fairytales but this is a new chapter in this marketing bubble.

Right now, a customer on NAV2015 for example must first pay the partner for an upgrade OnPrem and every 6 months they wait the upgrade will get more expensive.

Remember that at the point of writing this blog, there is no direct upgrade path like we had in the old days where a customer could upgrade from Navision 2.01 to Navision 4SP3 without any issues. A friend of mine who does all of my upgrades even has his own tools that handles one-step datamigration from Navision 2.x to NAV2018 or Business Central Wave I.

The upgrade from Wave I to Wave II is tedious at best since C/Side is retired. Now everything has to be done in PowerShell and Microsoft even started promoting doing stuff directly on the SQL Database in order to speed up the process.

My recommendation to QBS, but also to Microsoft is to somehow make this process more affordable and guarantee that even if a customer wants to upgrade 5 years from now there is still a mechanism that allows doing that.

I expect that in the next years the SQL Schema of Business Central will undergo many changes which is expensive fort he technology that Microsoft uses fort he upgrade.

The good news is that Microsoft employs the smartest people in the world and they seem to have a subscription to my blog. Let’s see where this ends. I’ve already heard some rumours that this problem is under the attention of the teams and I hope this article helps leadership prioritise this issue.

There is an elephand in the room so big, that nobody seems to see it.

#BCALHelp

It’s the week of NAVTechDays, the biggest Business Central Community event of the year and I thought it would be good to spend a few moments on the state of our community.

Business Central is taking off. According to Microsoft there are more than 4000 paying tenants and the average number of users per tentant is 10+ which is the sweetspot where Navision used to be strong.

I can also see it in my daily work, especially at ForNAV, where almost all of the support cases and pre-sales activities now involve onboarding new Business Central Partners. Especially from North America the uptake from Great Plains partners is great and it’s nice to see the entousiasm.

I’ve said it before and I’ll say it again. Business Central is by far the best ERP in the cloud and with no doubt the most flexible and easy to enhance. If you just forget for a moment that it used to be Navision and forget about the failed marketing it’s so easy to fall in love with the product once again.

Microsoft is much more quiet or less noisy. Working hard on improving the product and realising the vast amount of changes nessesairy to put dots on I’s and crosses on T’s.

The people who are new to the product need help getting started and Twitter is a nice medium to shout out for help.

For that reason Microsoft started the hashtag #BCALHelp and encourages the community to subscibe to the hastag and help their peers.

I think being the underdog, quietly working on being the best without bragging has been a position that was always good for Navision and it’s good for Business Central. Our customers are small entrepeneurs working hard and not as sensible for loud marketing as the big fortune 500.

Let’s be humble and be the best in our game. Take it slow and steady and make the best with what we have.

I’m sure that with that, NAVTechDays will soon be BCTechDays with the same pride and dignity as before serving the same great communities of Navision and Great Plains combined.

See you all in Antwerp!

Working with dates in AL vs. C/AL

It’s friday afternoon and I’m goofing around a bit with the ForNAV AL Converter. I ran into something I want to share.

AL seems to be more strickt in hardcoded dates than C/AL.

Example

Constant value '99993112D' is outside the range for a Date. The syntax for defining Date format is yyyymmddD, where D is a mandatory letter. For example, 20180325D, read as the 25th of March, 2018.

This should be 99991231D but C/Side exports it using your regional settings.

Fortunately we can fix this in C/Side by changing the code to

DMY2DATE(31,12,9999)

I only have to replace 42 instances for the project/partner I’m currently working on. Thank god it’s friday afternoon. 😉