Customizing Dynamics NAV
Discover different ways to customize the application to give you and your colleagues access to the features, functionality, and data that you need most.
Dynamics 365 2019 release wave 2 plan Discover the latest updates to Dynamics 365.Release Plan | Weekly Deployment Notes
Ace your Dynamics 365 deployment with packaged services delivered by expert consultants.Explore service offerings
Connect with the ISV success team on the latest roadmap, developer tool for AppSource certification, and ISV community engagements.
ISV self-service portal
The FastTrack program is designed to help you accelerate your Dynamics 365 deployment with confidence.
FastTrack Program | Finance and Operations TechTalks | Customer Engagement TechTalks | Talent TechTalks
We recently upgraded successfully our product to NAV2017. In fact, one day after the actual availability of the Belgian download, we had our upgraded product ready.
As promised, here is a short post about the challenges we faced during the upgrade. Probably not all challenges are represented here .. and I might have had issues that you won’t have :-). Keep that in mind.
First step for me always is an “upgrade” in the pure sense of the word. No redesign, no refactoring, no new features. Just the customized code transferred to the new version of NAV. That’s what this post is about. Next step (and release) for us is going to be incorporating the new features that Microsoft brings us.
Just to give you a feeling: this product of ours is quite big:
I was able to do this upgrade in less than 12 hours .. which is 4 times the time spent compared to last year. This is purely because of the significant refactoring that Microsoft has been doing. In numbers, this is what they did:
Do your own math ;-). The 96 deleted objects alone indicate a serious refactoring effort. And refactoring usually means: upgrade challenges.
How I did my upgrade
I upgraded our product in these steps:
After this final step, we had an upgraded database, including all upgrade code and upgrade toolkit for both the default application as my product.
Again, this doesn’t involve any significant code re-design to fit the new features. That’s what we will be doing from now on.
So, let’s dive into the things that are worth mentioning (in my book (no, I’m not writing a book …)).
During solving the conflicts, you run into objects that are quite refactored by Microsoft. I assume to know why they are doing this. Part of the reason must be facilitating more events. This needs to be done in refactored code .. . So let’s be clear: I totally support the fact that Microsoft is redesigning the code .. It’s a step we must take, although it doesn’t make the upgrade-life much easier.. .
These are a few points that I was struggling with.. :
COD414 and COD415 Release Sales/Purchase Document
OnRun moved to “Code” trigger. For the rest quite the same – so merging is quite fine .. . Though, I would have expected a bigger change. While you’re already changing the main trigger that will cause a conflict anyway – why not just refactor the whole thing. This is not really refactoring, this is moving and causing a conflict without any benefit…
COD448 – Job Queue Dispatcher
The Job Queue has totally changed. This is not a surprise, as it is running on a completely different platform, with a completely different concept, having multiple threads (workers?) waiting for the scheduler to drop something on its queue.. . I decided to ignore all my changes to the job queue, and start fresh. This will be something to look at after the upgrade.
COD5982 – Service-Post+Print
Microsoft removed a function “PrintReport” and put it on record-level, which means in this case: 4 places. I had one hook in this function .. and now it had to be placed on 4 places.. . This is the only place where “hooks” didn’t really serve me well as I don’t want to place one hook function in four places.. .
The redesign does make sense, though, so I’m not complaining. I created new hooks, and off we go :-).
COD82 – Sales-Post + Print
Similar changes (I like the consistency). Again, the PrintReport was moved to rec-level, which didn’t make my hook-moving going swell.. but I survived :-).
Must be the most refactored codeunit together with COD90. the code seems to still be all there in CU80, only in (local) functions. So this was really just a matter of moving my hooks to the right local function. You could see that the code structure was still quite the same, so it wasn’t that difficult to find out where the hook had to go.. .
A few other things caught my mind though, that wasn’t always that easy ..
I handled CU80 and CU90 manually in the database, and did all changes I did manually without automatic merge. It does make sense, because I could navigate through code to find out what to do in all 24 points I hooked into this codeunit. Tests will still have to show whether I did a good job or not ;-).
VAT calculation has moved to VATAmountLine table to “UpdateLines” function. Moving this function means moving your hook to another hook codeunit .. . It does make more sense, but in my book, this is one of the more challenging things to do ;-).
ApprovalsMgt Turned into Variant Façade
So, code like:
ApprovalsMgmt.DeleteApprovalEntry(DATABASE::”Sales Header”,”Document Type”,”No.”);
Needs to be changed to:
We used this kind of code quite a lot in our product.. . Some work, but the refactoring makes so much sense. Love it!
Default fields moved to “Item Template” .. . This is quite a big change, because we added 6 extra default fields .. and created some functionality on top of this. These default fields being moved to item template, meant we need to rethink our functionality as well .. . This is for after the upgrade, as in my opinion, “rethinking functionality” should not be part of the upgrade.
Pages is not easy. This is a refactoring-bit that I don’t like. Microsoft tends to put stuff on pages. Like:
I absolutely hate this design principle from the bottom of my heart. It’s unreadable, unmaintainable, unextendable, .. .
So if you would have changed or deleted any of these fields on pages, you would have conflicts. You get things like this:
In my case: LOADS of them.. . Thing is: also on moved fields you get this :(. I had conflicts on about all fields that we changed – just because of the design of these new features (page-field-level…).
This was just one example. Other very recurring conflicts were:
Furthermore, on a lot of pages, they don’t have closing semi-colon in code .. which makes it difficult to compile after you (automatically) merged code after it. Here is an example of Page30
A few numbers:
I was able to handle them all in just textfiles.. . But no advise here – you’ll just have to work your way through them :(.
In my case (BE upgrade from 2016 CU9 to 2017), a total of 96 objects were deleted. The chance you have references, table relations or whatever to any of these objects is quite big. This is something that you’ll need to handle after the upgrade while compiling your code. Very dependent of what and how you’re using these objects.
Why there are so many deleted objects. Well .. So much has been refactored .. like:
– reworked notifications
– reworked CRM wizards
– reworked job queue
In my case, only one conflict here. Namely the “Credit limit check” has seriously changed. It works with Notifications now. We tapped into it, so we needed to revise the complete solution (which ended up in removing it :-))
What I was really surprised about is some irregularities in the code of Microsoft. Sometimes, this was really confusing. One example that comes to mind is the variable “RowIsNotText” in page 46. This variable is used to handle the “Enabled” and “Editable” property of some fields. You would expect this variable to exist in all similar “subforms”. Well – no. In fact, in all other subforms, there was the similar but completely opposite variable “RowIsText”. Be careful for this!
Once I had compiled objects (all merged, imported and compilation errors solved), I started to work on my data upgrade. Of course I used the upgrade toolkit that comes with the product.
I had two issues in this.
The upgrade Toolkit contains errors in function: UpdateItemCategoryPostingGroups. It seems that a temp table in combination with an AutoIncrement doesn’t go well together. When you have multiple Item Categories, it failed on this function from the second entry .. . I did a dirty fix on this, doing this (just making sure the table is empty, so that the OnInsert code is being able to run.
Another issue was that Microsoft didn’t do a “INSERT(TRUE)” for the UpdateSMTPMailSetupEncryptPassword. The OnInsert needs to run, but Microsoft had put just “INSERT”, not “INSERT(TRUE”, which seemed like a bug (no GUID was created). We changed it to INSERT(TRUE).
Solving conflicts with VSCode
Just for the sake to get myself familiar with VSCode, I decided to handle conflicts in this editor. Sure, it’s not code, it’s just TXT files .. but why not :-). It is a code editor .. and text file or not – I’m editing code.
Here is how it looked like:
A few things that I really liked about this approach.
I will do this every time from now on :-).
I was happy to be able to have an upgrade in only 12 hours. Taking into account that so much was refactored, plus the most conflicts I had to solve in over 3 years .. it was still “just” 12 hours. Still, it’s 4 times the time that I spent in my previous upgrade .. . I hope this doesn’t mean that someone who did 1 month last time, will spend 4 months ;-).
Microsoft has given us the tools to do this as efficient as possible. Yes, I’m talking about PowerShell. My scripts on top of these building blocks has helped me tremendously again .. I can only recommend them for you.
“Hooks” helped me a lot again this time as well. Putting them into the refactored code was quite easy. I spent more time on some pages then I did on Codeunit 80.
So .. good luck, hope this helps you a bit.
Business Applications communities