Dynamics 365 Business Central

Hey everyone!

I’m off enjoying the March Break with my family this week but I wanted to get this out, since it’s (finally!) been announced by Microsoft that the product formerly known as Dynamics ‘Tenerife’ will be made available April 2, 2018 under the name Dynamics 365 Business Central.

As the announcement states, it’s going to be available April 2, 2018 to 14 countries: United States, Canada, United Kingdom, Denmark, Netherlands, Germany, Spain, Italy, France, Austria, Switzerland, Belgium, Sweden, and Finland. Australia and New Zealand will be available on July 1, 2018. Take note that you must purchase Dynamics 365 Business Central through a Cloud Solution Provider (CSP) partner.

I don’t have much else to say right now, other than I’ve been working with Dynamics 365 Business Central for a while now and I think everyone’s going to love it! This product is moving fast and the advancements being made are amazing! Definitely some very exciting times ahead!

If you want to read more, check out the Dynamics 365 Business Central website here.

Until next time….happy coding!

Advertisements

AL Extensions: Translate your solution using Microsoft Dynamics Lifecycle Services

Hi everyone!

Today’s post is about language translations. I’ve not really done much with language translations in the past, but it always seemed as though it was a very tedious thing to have to do.

This post though is going to show you how to do it quite quickly, and if all goes well you can translate your AL extension in a matter of minutes.

Pre-Requisite

Note that in order to perform the tasks in this post, you will need access to Microsoft Dynamics Lifecycle Services (LCS). If you do not have access contact your system administrator, or the person that manages your CustomerSource/PartnerSource account, as the systems are linked in some way.

Let’s Get Started

Assuming you have already developed your AL extension, you need to enable the new translation feature. You can do that by adding the following line to your app.json:

"features": ["TranslationFile"]

This feature will cause a new translation file to be generated when the extension is built. The translation files are created using the standard XLIFF format that is used to pass data between system for the purposes of language translation. For more info on XLIFF, check here. You will find the translation file at the root of your AL project in a Translations folder.

You’re also going to need to change all of your ML properties as they are being deprecated (as of this post though they are still available). You can read more about that here.

Ok, you have now enabled the new translation file feature, and you’ve updated all of your ML properties, you need to build your extension. Once that completes, look for the newly created XLF file in the Translations folder. This is the file that we need to submit to the translation service.

The Translation Service

Before we get into submitting the file, note that in my solution my base language is English (US). I’ll be translating that to Canadian French. Substitute the appropriate languages for your solution.

Here are the steps to perform the translation:

TranslationServiceTile

  • Select the ‘+’ button at the top left to make a new request and fill in the request based on your desired translation. Make sure to select Microsoft Dynamics NAV as the product and the appropriate product version.

TranslationRequest

  • Once you have filled in your request, press Create to submit the request. At this point you just wait. You should receive an email from LCS stating that “A new request has been created.”
  • After a short period of time (for me this was only about 2 minutes!!) you will receive another email from LCS stating “The request has been completed.”
  • Follow the link in the email and you will be brought to a page that shows you the details of your translation request.
  • Click Request output at the left side of the screen.
  • Click the DownloadOutputLink link to download your translated XLF file. and extract it to the Translations folder in your AL project. It will have a new file name so it should not overwrite your existing file. Do not remove the original XLF file as that still represents the base language of your extension!

That’s it!

Now all you have left to do is to rebuild your extension with the new translation file and voila…..you now have a multi-language extension! Test it out by changing to the appropriate language in the web client.

Ongoing Maintenance

Once you have non-base translation files in your AL project, they do not get updated when the extension is built. For example, if you add a new field with a caption and build your extension, the base language XLF will get updated to include the new field. Your non-base XLF files will not, so you will need to revisit LCS and submit a new base language file to get those updated.

Hopefully this service has works as well for you as it seems to for me. I was actually quite shocked at how fast I was able to get the translated file back.

That’s all for now, happy coding!

AL Extensions: Accessing the Device Camera

If you’ve been doing any V2 extension development, you like are aware that we cannot use any .Net interop in our code.

While on premise V2 development will eventually gain access to .Net variable types, if you’re coding your extension to run in AppSource, you will remain locked away from using .Net interop in your code because the risk of these external components is too large for shared cloud servers.

Unfortunately this means that we lost the ability to interact with the device camera, as it was accessed using .Net.

In C/AL, the code to take a picture with the device camera looked like this:

TakeNewPicture()
   IF NOT CameraAvailable THEN
      EXIT;
   CameraOptions := CameraOptions.CameraOptions;
   CameraOptions.Quality := 50;
   CameraProvider.RequestPictureAsync(CameraOptions);

It’s simple enough code, but the problem in the above example is that both CameraProvider and CameraOptions are .Net variables, and therefore cannot be used in V2 extension development.

I’m happy to say though that this problem has been resolved. Yes, the underlying architecture still uses .Net controls, but Microsoft has introduced a new Camera Interaction page which acts basically like an api layer. Through this api layer you can interact with the .Net camera components just as you did in C/AL.

Not a huge change to wrap your head around at all. In your extension you will code against the Camera Interaction page instead of against the .Net controls directly. Inside the page are all the original camera functions that you were used to using before.

This greatly simplifies our extension code and allows us now to use the camera from our extensions.

The code to take a picture would now look like this:

local procedure TakePicture();
    var
        CameraInteraction: Page "Camera Interaction";
        PictureStream: InStream;
    begin
        CameraInteraction.AllowEdit(true);
        CameraInteraction.Quality(100);
        CameraInteraction.EncodingType('PNG');
        CameraInteraction.RunModal;
        if(CameraInteraction.GetPicture(PictureStream)) then begin
            Picture.ImportStream(PictureStream, CameraInteraction.GetPictureName());
        end;
    end;

That’s it! Now you can use the device camera from your V2 extensions.

Happy coding!

AL Extensions: Importing and Exporting Media Sets

One of the things that has changed when you are building V2 extensions for a cloud environment is that you cannot access most functions that work with physical files.

This presents a bit of a challenge when it comes to working with the media and media set field types, as the typical approach is to have an import and export function so that a user can get pictures in and out of the field.

An example of this is the Customer Picture fact box that’s on the Customer Card:

WorkingWithMediaFields1

As you can see, the import and export functions in C/Side leverage the FileManagement codeunit in order to transfer the picture image to and from a physical picture file. These functions are now blocked.

So…..we have got to take another approach. Enter streams.

Using the in and out stream types we can recreate the import and export functions without using any of the file based functions.

An import function would look like the following. In this example, the Picture field is defined as a Media Set field.

local procedure ImportPicture();
var
   PicInStream: InStream;
   FromFileName: Text;
   OverrideImageQst: Label 'The existing picture will be replaced. Do you want to continue?', Locked = false, MaxLength = 250;
begin
   if Picture.Count > 0 then
     if not Confirm(OverrideImageQst) then
       exit;

  if UploadIntoStream('Import', '', 'All Files (*.*)|*.*', FromFileName, PicInStream) then begin
    Clear(Picture);
    Picture.ImportStream(PicInStream, FromFileName);
    Modify(true);
  end;
end;

The UploadIntoStream function will prompt the user to choose a local picture file, and from there we upload that into an instream. At no point do we ever put the physical file on the server. Also note that the above example will always override any existing picture. You do not have to do this as media sets allow for multiple pictures. I’m just recreating the original example taken from the Customer Picture page.

For the export we have to write a bit more code. When using a Media Set field, we do not have access to any system function that allows us to export to a stream. To deal with this all we need to do is loop through the media set and get each of the corresponding media records. Once we have that then we can export each of those to a stream.

That would look like this:

local procedure ExportPicture();
var
   PicInStream: InStream;
   Index: Integer;
   TenantMedia: Record "Tenant Media";
   FileName: Text;
begin
   if Picture.Count = 0 then
      exit;

   for Index := 1 to Picture.Count do begin
      if TenantMedia.Get(Picture.Item(Index)) then begin
         TenantMedia.calcfields(Content);
         if TenantMedia.Content.HasValue then begin
            FileName := TableCaption + '_Image' + format(Index) + GetTenantMediaFileExtension(TenantMedia);
            TenantMedia.Content.CreateInStream(PicInstream);
            DownloadFromStream(PicInstream, '', '', '', FileName);
         end;
      end;
   end;
end;

We use the DownloadFromStream function to prompt the user to save each of the pictures in the media set. As in our first example, there are no physical files ever created on the server, so we’re cloud friendly!

You may notice that I use the function GetTenantMediaFileExtension in the export example to populate the extension of the picture file. Since the user can upload a variety of picture file types, we need to make sure we create the file using the correct format.

The function to do this is quite simple, however there is no current function in the product to handle it, so you’ll have to build this yourself for now. Hopefully in the near future this function will be added by Microsoft.

local procedure GetTenantMediaFileExtension(var TenantMedia: Record "Tenant Media"): Text;
begin
   case TenantMedia."Mime Type" of
      'image/jpeg' : exit('.jpg');
      'image/png' : exit('.png');
      'image/bmp' : exit('.bmp');
      'image/gif' : exit('.gif');
      'image/tiff' : exit('.tiff');
      'image/wmf' : exit('.wmf');
   end;
end;

Until next time, happy coding!

 

Create a Dynamics 365 Sandbox Environment

Microsoft has given us the ability to create a sandbox environment based on the Dynamics 365 platform. This will allow you to try out new setups, extensions, and even develop new extensions in a safe isolated environment. This is perfect for testing new extensions in a true Dynamics 365 environment.

Each Dynamics 365 subscription is allowed to create one sandbox environment for no additional charge. You can even tear down and reset your sandbox as necessary.

To create a sandbox environment:

  1. Sign in to your production instance of the Financials service.
  2. Choose the Search for Page or Report icon, enter Sandbox Environment, and then choose the related link
  3. Select Create.
    Another tab in your browser will open for finishing the setup of your sandbox environment.
  4. When the sandbox environment is ready, you will be redirected to sandbox environment’s Welcome wizard.
  5. Choose Learn more to read about scenarios that you can try in a sandbox environment. Or, choose Close to continue to the Role Center of your Financials sandbox instance.
  6. At the top of the Role Center, a notification appears to inform you that this is a sandbox environment. You can also see the type of the environment in the title bar of the client.

Once the sandbox has been created, you can access each environment directly with the following URLs:

For more information, see the original Microsoft article here.

Happy coding!

Dynamics 365 ‘Tenerife’ Release Plan

Quick update on the release plan for the next iteration of Dynamics 365 ‘Tenerife’ (fka Dynamics NAV).

The next release for on-premise deployments was announced to be in the spring of 2018. This is a change from the typical October releases that we’ve been used to for the past 7 years or so.

We’re not sure what the final product name will be at this point.

This change in the release date came as quite a shock to the audience at Directions NA 2017. So much of a shock that Microsoft announced during the closing keynote that they will look into the current release plan to see if there’s anything they can do to get it out ahead of plan.

That’s all for now, happy coding!

Thoughts on Directions NA 2017

I’m back home after spending some time at Directions NA 2017. It was…..crazy and amazing! It’s always a fun and informative conference, and this year definitely did not disappoint.

I’m not going to focus on ‘the crazy’, as I’m sure you’ve probably seen countless other posts about it already. 🙂

Dynamics 365 ‘Tenerife’. Is it the final name? No. Is the NAV name being dropped? Sounds like it.

Dynamics 365 Tenerife: it’s cloud; it’s on-premise; it’s really freakin’ cool!

One more thing. No matter if you are a coder, an implementer, a sales person, or a little bit of everything, things are changing, and they’re changing FAST. Scary? Of course…..change always is, but I have 100% confidence that Microsoft’s direction is the right direction to go. We have been living in an online world for a number of years. No longer is the message “the cloud is coming”. The message is now “the cloud is here”. Hopefully you’ve been moving to the cloud already. If not, you are behind the times; it’s time to get your products to the cloud ASAP!

For developers, you have to put back on your learning hat and if you’ve not already started, begin looking at extension development using the new development tools, namely Visual Studio Code. It’s a new tool, but not “really” a new language. C/AL is a great language, so why would Microsoft do away with it? Consider the new AL language as ‘C/AL 2.0’ if you want. Same syntax, plus a load of new features that makes development even faster than it was in C/Side. With built in object types to connect to web services or process xml data, to new string builder commands, the development platform has been improved to an absolutely amazing level…….and that’s not even considering all of the goodies that Visual Studio Code brings us. Customize your development tool to however you like using a massive library of different extensions. Visual Studio Code has quickly become my go-to tool for much more than AL coding.

There’s so many cool things that need to be talked about in detail. The Microsoft Graph API that is being developed for the Dynamics 365 platform is something I want to spend some time with in the near future. Finally having a documented common set of APIs is something that I think is going to make our lives as developers extremely better…….and yes, the APIs work on premise too. 🙂

So many things to learn outside of what we’d typically refer to as the “NAV system”. Case in point, I spoke at a session regarding test drives on AppSource, which up until 2 weeks ago, was a completely foreign topic that I knew nothing about, and never thought I’d need to know anything about. Turns out though, with minimal development work, it’s incredibly easy to hook up your Dynamics 365 published app so that any Office 365 user (admin or not) can spin up a session to try it out, free of charge to them.

I know I’m probably forgetting a load of other cool things that were covered at Directions NA 2017, but trust me when I say that Microsoft is stepping on the pedal hard and going full steam ahead. Dynamics 365 Tenerife is a testament to that for sure.

It’s all so very exciting!

Until next time, happy coding!