Using the Translation Service for G/L Source Names

Until now I have had my G/L Source Names extension in English only.

Now the upcoming release of Microsoft Dynamics 365 Business Central I need to supply more languages.  What does a man do when he does not speak the language?

I gave a shout out yesterday on Twitter asking for help with translation.  Tobias Fenster reminded me that we have a service to help us with that.  I had already tried to work with this service and now it was time to test the service on my G/L Source Names extension.

In my previous posts I had created the Xliff translation files from my old ML properties.  I manually translated to my native language; is-IS.

I already got a Danish translation file sent from a colleague.

Before we start; I needed to do a minor update to the AdvaniaGIT tools.  Make sure you run “Advania: Go!” to update the PowerShell Script Package.  Then restart Visual Studio Code.

Off to the Microsoft Lifecycle Services to utilize the translation service.

Now, let’s prepare the Xliff files in Visual Studio Code.  From the last build I have the default GL Source Names.g.xlf file.  I executed the action to create Xliff files.

This action will prompt for a selection of language.  The selection is from the languages included in the NAV DVD.

After selection the system will prompt for a translation file that is exported from FinSql.  This I already showed in a YouTube Video.  If you don’t have a file from FinSql you can just cancel this part.  If you already have an Xliff file for that language then it will be imported into memory as translation data and then removed.

This method is therefore useful if you want to reuse the Xliff file data after an extension update.  All new files will be based on the g.xlf file.

I basically did this action for all 25 languages.  I already had the is-IS and da-DK files, so they where updated.  Since the source language is en-US all my en-XX files where automatically translated.  All the other languages have translation state set to “needs-translation”.

</trans-unit><trans-unit id="Table 102911037 - Field 1343707150 - Property 2879900210" size-unit="char" translate="yes" xml:space="preserve">
  <source>Source Name</source>
  <target state="needs-translation"></target><note from="Developer" annotates="general" priority="2" />
  <note from="Xliff Generator" annotates="general" priority="3">Table:O4N GL SN - Field:Source Name</note>
</trans-unit>

All these files I need to upload to the Translation Service.  From the Lifecycle Services menu select the Translation Service.  This will open the Translation Service Dashboard.

Press + to add a translation request.

I now need to zip and upload the nl-NL file from my Translations folder.

After upload I Submit the translation request

The request will appear on the dashboard with the status; Processing.  Now I need to wait for the status to change to Completed.  Or, create requests for all the other languages and upload files to summit.

When translation has completed I can download the result.

And I have a translation in state “needs-review-translation”.

<trans-unit id="Table 102911037 - Field 1343707150 - Property 2879900210" translate="yes" xml:space="preserve">
  <source>Source Name</source>
  <target state="needs-review-translation" state-qualifier="mt-suggestion">Bronnaam</target>
  <note from="Xliff Generator" annotates="general" priority="3">Table:O4N GL SN - Field:Source Name</note>
</trans-unit>

Now I just need to complete all languages and push changes to GitHub.

Please, if you can, download your language file and look at the results.

Upgrading my G/L Source Names Extension to AL – step 4 addendum

In the last blog post we completed the translation to our native language.  Since then I have learned that I also need to include translation files for EN-US, EN-GP and EN-CA.

With the latest update of AdvaniaGIT tools that was an easy task.  Just asked to create Xlf file for these languages and skipped the part where we import C/AL translation.

I have also been pointed to a new tool that can work with Xlf files.  Multilingual Editor: https://marketplace.visualstudio.com/items?itemName=MultilingualAppToolkit.MultilingualAppToolkitv40

Now I call out to all who are ready to help me with the translation.  Please fork my NAV2018 repository and send me Xlf translation files for your native language.  Or just download one of the translation files and send me your language.

Our next step is to code sign the App file and send it to Microsoft.

Upgrading my G/L Source Names Extension to AL – step 4

We are on a path to upgrade G/L Source Names from version 1 to version 2.  This requires conversion from C/AL to AL, data upgrade and number of changes to the AL code.

A complete check list of what you need to have in your AL extension is published by Microsoft here.

Our task for today is to translate the AL project into our native language.

To make this all as easy as I could I added new functionality to the AdvaniaGIT module and VS Code extension.  Make sure to update to the latest release.

To translate an AL project we need to follow the steps described by Microsoft here.

To demonstrate this process I created a video.

 

Upgrading my G/L Source Names Extension to AL – step 3

When upgrading an extension from C/AL to AL (version 1 to version 2) we need to think about the data upgrade process.

In C/AL we needed to add two function to an extension Codeunit to handle the installation and upgrade.  This I did with Codeunit 70009200.  One function to be execute once for each install.

PROCEDURE OnNavAppUpgradePerDatabase@1();
VAR
  AccessControl@70009200 : Record 2000000053;
BEGIN
  WITH AccessControl DO BEGIN
    SETFILTER("Role ID",'%1|%2','SUPER','SECURITY');
    IF FINDSET THEN REPEAT
      AddUserAccess("User Security ID",PermissionSetToUserGLSourceNames);
      AddUserAccess("User Security ID",PermissionSetToUpdateGLSourceNames);
      AddUserAccess("User Security ID",PermissionSetToSetupGLSourceNames);
    UNTIL NEXT = 0;
  END;
END;

And another function to be executed once for each company in the install database.

PROCEDURE OnNavAppUpgradePerCompany@2();
VAR
  GLSourceNameMgt@70009200 : Codeunit 70009201;
BEGIN
  NAVAPP.RESTOREARCHIVEDATA(DATABASE::"G/L Source Name Setup");
  NAVAPP.RESTOREARCHIVEDATA(DATABASE::"G/L Source Name User Setup");
  NAVAPP.DELETEARCHIVEDATA(DATABASE::"G/L Source Name");

  NAVAPP.DELETEARCHIVEDATA(DATABASE::"G/L Source Name Help Resource");
  NAVAPP.DELETEARCHIVEDATA(DATABASE::"G/L Source Name User Access");
  NAVAPP.DELETEARCHIVEDATA(DATABASE::"G/L Source Name Group Access");

  GLSourceNameMgt.PopulateSourceTable;
  RemoveAssistedSetup;
END;

For each database I add my permission sets to the installation users and for each company I restore the setup data for my extension and populate the lookup table for G/L Source Name.

The methods for install and upgrade have changed in AL for extensions version 2.  Look at the AL documentation from Microsoft for details.

In version 2 I remove these two obsolete function from my application management Codeunit and need to add two new Codeunits, one for install and another for upgrade.

codeunit 70009207 "O4N GL Source Name Install"
{
    Subtype = Install;
    trigger OnRun();
    begin
    end;

    var
    PermissionSetToSetupGLSourceNames : TextConst ENU='G/L-SOURCE NAMES, S';
    PermissionSetToUpdateGLSourceNames : TextConst ENU='G/L-SOURCE NAMES, E';
    PermissionSetToUserGLSourceNames : TextConst ENU='G/L-SOURCE NAMES';

    
    trigger OnInstallAppPerCompany();
    var
        GLSourceNameMgt : Codeunit "O4N GL SN Mgt";
    begin
        GLSourceNameMgt.PopulateSourceTable;
        RemoveAssistedSetup;
    end;

    trigger OnInstallAppPerDatabase();
    var
        AccessControl : Record "Access Control";
    begin
        with AccessControl do begin
            SETFILTER("Role ID",'%1|%2','SUPER','SECURITY');
            if FINDSET then repeat
                AddUserAccess("User Security ID",PermissionSetToUserGLSourceNames);
                AddUserAccess("User Security ID",PermissionSetToUpdateGLSourceNames);
                AddUserAccess("User Security ID",PermissionSetToSetupGLSourceNames);
            until NEXT = 0;
        end;
    end;

  local procedure RemoveAssistedSetup();
  var
    AssistedSetup : Record "Assisted Setup";
  begin
    with AssistedSetup do begin
      SETRANGE("Page ID",PAGE::"O4N GL SN Setup Wizard");
      if not ISEMPTY then
        DELETEALL;
    end;
  end;

  local procedure AddUserAccess(AssignToUser : Guid;PermissionSet : Code[20]);
  var
    AccessControl : Record "Access Control";
    AppMgt : Codeunit "O4N GL SN App Mgt.";
    AppGuid : Guid;
  begin
    EVALUATE(AppGuid,AppMgt.GetAppId);
    with AccessControl do begin
      INIT;
      "User Security ID" := AssignToUser;
      "App ID" := AppGuid;
      Scope := Scope::Tenant;
      "Role ID" := PermissionSet;
      if not FIND then
        INSERT(true);
    end;
  end;

}

In the code you can see that this Codeunit is of Subtype=Install.  This code will  be executed when installing this extension in a database.

To confirm this I can see that I have the G/L Source Names Permission Sets in the Access Control table .

And my G/L Source Name table also has all required entries.

Uninstalling the extension will not remove this data.  Therefore you need to make sure that the install code is structured in a way that it will work even when reinstalling.  Look at the examples from Microsoft to get a better understanding.

Back to my C/AL extension.  When uninstalling that one the data is moved to archive tables.

Archive tables are handled with the NAVAPP.* commands.  The OnNavAppUpgradePerCompany command here on top handled these archive tables when reinstalling or upgrading.

Basically, since I am keeping the same table structure I can use the same set of commands for my upgrade Codeunit.

codeunit 70009208 "O4N GL SN Upgrade"
{
    Subtype=Upgrade;
    trigger OnRun()
    begin
        
    end;
    
    trigger OnCheckPreconditionsPerCompany()
    begin

    end;

    trigger OnCheckPreconditionsPerDatabase()
    begin

    end;
    
    trigger OnUpgradePerCompany()
    var
        GLSourceNameMgt : Codeunit "O4N GL SN Mgt";
        archivedVersion : Text;
    begin
        archivedVersion := NAVAPP.GetArchiveVersion();
        if archivedVersion = '1.0.0.1' then begin
            NAVAPP.RESTOREARCHIVEDATA(DATABASE::"O4N GL SN Setup");
            NAVAPP.RESTOREARCHIVEDATA(DATABASE::"O4N GL SN User Setup");
            NAVAPP.DELETEARCHIVEDATA(DATABASE::"O4N GL SN");

            NAVAPP.DELETEARCHIVEDATA(DATABASE::"O4N GL SN Help Resource");
            NAVAPP.DELETEARCHIVEDATA(DATABASE::"O4N GL SN User Access");
            NAVAPP.DELETEARCHIVEDATA(DATABASE::"O4N GL SN Group Access");

            GLSourceNameMgt.PopulateSourceTable;
        end;
    end;

    trigger OnUpgradePerDatabase()
    begin

    end;

    trigger OnValidateUpgradePerCompany()
    begin

    end;

    trigger OnValidateUpgradePerDatabase()
    begin

    end;
    
}

So, time to test how and if this works.

I have my AL folder open in Visual Studio Code and I use the AdvaniaGIT command Build NAV Environment to get the new Docker container up and running.

Then I use Update launch.json with current branch information to update my launch.json server settings.

I like to use the NAV Container Helper from Microsoft  to manually work with the container.  I use a command from the AdvaniaGIT module to import the NAV Container Module.

The module uses the container name for most of the functions.  The container name can be found by listing the running Docker containers or by asking for the name that match the server used in launch.json.

I need my C/AL extension inside the container so I executed

Copy-FileToNavContainer -containerName jolly_bhabha -localPath C:\NAVManagementWorkFolder\Workspace\GIT\Kappi\NAV2017\Extension1\AppPackage.navx -containerPath c:\run

Then I open PowerShell inside the container

Enter-NavContainer -containerName jolly_bhabha

Import the NAV Administration Module

Welcome to the NAV Container PowerShell prompt

[50AA0018A87F]: PS C:\run> Import-Module 'C:\Program Files\Microsoft Dynamics NAV\110\Service\NavAdminTool.ps1'

Welcome to the Server Admin Tool Shell!

[50AA0018A87F]: PS C:\run>

and I am ready to play.  Install the C/AL extension

Publish-NAVApp -ServerInstance NAV -IdePath 'C:\Program Files (x86)\Microsoft Dynamics NAV\110\RoleTailored Client\finsql.exe' -Path C:\run\AppPackage.navx -SkipVerification

Now I am faced with the fact that I have opened PowerShell inside the container in my AdvaniaGIT terminal.  That means that my AdvaniaGIT commands will execute inside the container, but not on the host.

The simplest way to solve this is to open another instance of Visual Studio Code.  From there I can start the Web Client and complete the install and configuration of my C/AL extension.

I complete the Assisted Setup and do a round trip to G/L Entries to make sure that I have enough data in my tables to verify that the data upgrade is working.

I can verify this by looking into the SQL tables for my extension.  I use PowerShell to uninstall and unpublish my C/AL extension.

Uninstall-NAVApp -ServerInstance NAV -Name "G/L Source Names"
Unpublish-NAVApp -ServerInstance NAV -Name "G/L Source Names"

I can verify that in my SQL database I now have four AppData archive tables.

Pressing F5 in Visual Studio Code will now publish and install the AL extension, even if I have the terminal open inside the container.

The extension is published but can’t be installed because I had previously installed an older version of my extension.  Back in my container PowerShell I will follow the steps as described by Microsoft.

[50AA0018A87F]: PS C:\run> Sync-NAVApp -ServerInstance NAV -Name "G/L Source Names" -Version 2.0.0.0
WARNING: Cannot synchronize the extension G/L Source Names because it is already synchronized.
[50AA0018A87F]: PS C:\run> Start-NAVAppDataUpgrade -ServerInstance NAV -Name "G/L Source Names" -Version 2.0.0.0
[50AA0018A87F]: PS C:\run> Install-NAVApp -ServerInstance NAV -Tenant Default -Name "G/L Source Names"
WARNING: Cannot install extension G/L Source Names by Objects4NAV 2.0.0.0 for the tenant default because it is already installed.
[50AA0018A87F]: PS C:\run>

My AL extension is published and I have verified in my SQL server that all the data from the C/AL extension has been moved to the AL extension tables and all the archive tables have been removed.

Back in Visual Studio Code I can now use F5 to publish and install the extension again if I need to update, debug and test my extension.

Couple of more steps left that I will do shortly.  Happy coding…

 

Upgrading my G/L Source Names Extension to AL – step 2

So, where is step 1?  Step 1 was converting C/AL code to AL code.  This we did with AdvaniaGIT and was demonstrated here.

First thing first!  I received the following email from Microsoft.

Hello,

The decision has been made by our SLT, that the use of a Prefix or Suffix is now a mandatory requirement. If you are already using this in your app(s), great. If not, you will want to do so.

We are coming across too many collisions between apps in our internal tests during builds and have seen some in live tenants as well. It makes the most sense to make this a requirement now. If you think about it in a live situation, if a customer installs an app before yours and then tries yours but gets collision issues, they may just decide to not even continue on with yours.

Also, I have been made aware that adding a prefix or suffix after you already have a v2 app published can make the process complicated for you. Therefore, since you all have to convert to v2 anyway, now is a good time to add in the prefix/suffix.

The following link provides the guidelines around using it here

If you haven’t reserved your prefix yet, please email me back to reserve one (or more if needed).

Thank you,

Ryan

Since my brand is Objects4NAV.com I asked for 04N as my prefix and got it registered.  Since we got this information from Microsoft, every object that we develop in NAV 2018 now has our companies prefix in the name.

Starting my AL development by opening Visual Studio Code in my repository folder.  I updated my setup.json to match the latest preview build as Docker container and then selected to Build NAV Environment using AdvaniaGIT.

After download and deployment of the container I noticed that the container had a brand new version of the AL Extension for Visual Studio Code.  I looked at the version installed and that was an older version.

I uninstalled the AL Language extension and restarted Visual Studio Code.

As you can see on the screenshot above we now don’t have any AL Language extension installed.  I executed the Build NAV Environment command from AdvanaiGIT to install the extension on the Docker container.  In this case I already had a container assigned to my branch so only three things happened.

  • uidOffset in the container database was updated.  This is recommended for C/AL development.
  • License file is updated in the container database and container service.  The license used is the one configured in branch setup.json or the machine settings GITSettings.json
  • AL Language Extension is copied from the container to the host and installed in Visual Studio Code.

Again, restarting Visual Studio Code to find that the latest version of AL Language Extension has been installed.

I then executed two AdvaniaGIT actions.

  • Update Launch.json with current branch environment.  This will update the host name and the service name in my AL Launch.json file to make sure that my AL project will be interacting with the branch container.
  • Open Visual Studio Code in AL folder.  This will open another instance of Visual Studio Code in the AL folder.

Immediately after Visual Studio Code was opened it asked for symbols and I agreed that we should download them from the container.

Everything is now ready for AL development using the latest build that Microsoft has to offer.

I started  Edit – Replace in Files in Visual Studio Code.  All my objects have a name that start with G/L Source Name.  I used this knowledge to apply the prefix.

By starting with the double quote I make sure to only update the object names and not captions.  All captions start with a single quote.  I got a list of all changes and needed to confirm all changes.

The field name I add to G/L Entry table does not match this rule so I needed to rename that my self.  Selecting the field name and pressing F2 allows me to rename a field and have Visual Studio Code update all references automatically.

Pressing F5 started my build, publish and debug.

My extension is installed and ready for testing.

There are a few more steps that I need to look into before publishing the new version of G/L Source Names to Dynamics 365.  These steps will appear here in the coming days.  Hope this will be useful to you all.

Using AdvaniaGIT – Convert G/L Source Names to AL

Here we go.

The NAV on Docker environment we just created can be used for the task at hand.  I have an Extension in Dynamics 365 called G/L Source Names.

I need to update this Extension to V2.0 using AL.  In this video I go through the upgrade and conversion process using AdvainaGIT and Visual Studio Code.

In the first part I copy the deltas from my Dynamics 365 Extension into my work space and I download and prepare the latest release of NAV 2018 Docker Container.

Using our source and modified environments we can build new syntax objects and new syntax deltas. These new syntax deltas are then converted to AL code.

 

My first Dynamics 365 Extension – Offer ‘G/L Source Names’ is live

So, back from summer vacation and time to blog…

Early this month I got this email:

Offer ‘G/L Source Names’ is live

Congratulations! Your offer ‘G/L Source Names’ has been successfully published and is available publicly.

Next Steps

Below are the published link(s) for this offer. Please use these to verify and validate end to end experience.

Microsoft AppSource

If you need to update your offer click here.

Reply all to this email in case you need any help.

Thank you,
Microsoft AppSource team

If you follow these links you should see that the publishing portal for Dynamics 365 AppSource has been changed.

My App was automatically migrated from Azure MarketPlace to Cloud Partner Portal.  Got this email from Microsoft:

Greetings,

Azure Marketplace will be migrating your VM offers to the Cloud Partner Portal – the new and improved portal for publishing your single VM offers and getting valuable insights about your Azure Marketplace business, on Monday, 17th July 2017.

What should you expect during migration?

Migration will be done by Azure marketplace team and there is no action needed from you. Post-migration, you will start managing your single VM offers in the new Cloud Partner Portal.

During the migration, you will be unable to make updates to your offers via the publishing portal. Migration will be completed on the same day.

Will my offer be available on Azure Marketplace during migration?

Yes, migration will not affect your Azure Marketplace listing.

Refer to migration documentation here for FAQs.

You can log in to the Cloud Partner Portal at https://cloudpartner.azure.com. Documentation about the Cloud Partner Portal and publishing single VM offers can be found here.

General questions on the new CPP itself, reach out to cpp-public-preview@microsoft.com and we will follow up with you! If you have specific D365 questions, reach out to d365val@microsoft.com

Regards,
Azure Marketplace Team

And that is not all.  I also got this email from Microsoft:

Hello,

The Dynamics 365 for Financials Extension Team wants to inform you of some important information. As of August 1st, 2017, we will begin accepting version 2.0 extensions for validation. Version 2.0 extensions is a much improved experience and represent our future direction for extensions. We will continue to accept v1 extensions until October 1. Please plan accordingly.

If you have a v1 app that is currently in process of validation, or if you have one that is currently published in App Source, you can begin (at your convenience) to convert your v1 app to v2. Refer to the site here for information on how to convert your app. We will work with you as well for the conversion so please direct any questions to d365val@microsoft.com.

https://aka.ms/BeDeveloperforApps and https://aka.ms/GetStartedWithApps has all the information to date around Extensions v2.0. If there is anything you cannot find there, you can always contact the email with any further questions.

Best Regards

D365 Extension Validation Team

This blog series will be continued where I will be converting this App to Extension v2.0 using VSCode.  Stay tuned…

My first Dynamics 365 Extension – In maintenance mode

This morning I got this email:

Hi Gunnar,

I just wanted to inform you that your extension passed validation on US, CA, and GB. We will now get your extension checked in and it will go into the June (Update 7) release.

I am excited to see if users will start to install my app.  As more markets will open for Dynamics 365 for Financials (D365) I will need to support more languages to my App.

If you can help me with your local language please ping me.  The App is available on my GitHub site; https://github.com/gunnargestsson/nav2017/tree/GLSourceNames.  If you would like to install this extension or merge the deltas into your solution, again just ping me.

If you are in the process of creating an Extension for Dynamics 365 for Financials you can now request a Financials sandbox environment.  I installed this on my local virtual machine and this was an essential part of validating the extension.  You will need to sign up for the CTP program, which provides you with a prerelease version of Dynamics 365 for Financials. After you have signed the CTP Agreement, you are directed to a page that contains information about how to download the latest builds and configure a local computer or a Microsoft Azure VM for Dynamics 365 for Financials. If you have questions or feedback regarding this, please send an e-mail to: d365-smb@microsoft.com.

Also, take a look at the updated aka.ms/AppsForFinancials page for more information.

Finally, if you take a look at the source for G/L Source Names you will find a setup.json file.  This file has all the information needed for my GIT Source Control.  As promised in NAV TechDays 2016 I am releasing the AdvaniaGIT to be community project.  Stay tuned to Dynamics.is as I will be writing blogs about this project in the coming days and weeks.

 

Building Assisted Setup for Dynamics 365 for Financials

I had my Assisted Setup wizard up and running on NAV 2017.  Everything looked fine but when the extension was being validated nothing worked.

So, there is a difference between NAV 2017 and Dynamics 365 for Financials.

Remember the session on Design Patterns in NAV 2017 on NAV TechDays 2016?  Microsoft showed what they where planning in regards to assisted setup and manual setup.  This has been implemented in Dynamics 365 for Financials but has not been released for NAV 2017.

One of the feedback Microsoft got from us MVPs was about the Assisted Setup not using the discovery pattern (you will know what I am talking about after watching the session above).  The Assisted Setup table (1803) in NAV 2017 is the one used to register all assisted setup pages.  The problem was that a record for an extension in this table was not removed during uninstall.

Now we have a new table, Aggregated Assisted Setup (1808) that is a temporary table using the discovery pattern.  We also have a new discovery pattern for the Manual Setup with another new table, Business Setup (1875).  You can download these new tables from here (NewD365SetupTables) or wait for them to be released in one of the upcoming NAV 2017 Cu releases.

Here you can also download the guidelines for the new setup pattern (AssistedSetupGuidelines).  My code looks like this.

The Icon file that I created is 240x240px with foreground (RGB 55 55 55) and background (RGB 250 250 235).

More to come, stay tuned…