This blog post will explain how to create a customer in Dynamics 365 for Finance and Operations (D365FO) with an integrated VIES check using PowerApps. For European customers, it is a common requirement to check the validity of the VAT number. The VAT Information Exchange Service (VIES) created by the European Union is a tool to facilitate this.
Introduction
VIES has a SOAP service available for directly checking VAT numbers, which you can read more about here. In this post we will create a complete app with all the required tools.
The process in this app will be that a user enters a VAT number, the VAT number will be checked with VIES and if it is valid the user can move on to the next screen if it is not valid the user can’t continue.
At the second screen, the user can provide additional information and press confirm, after confirming the customer is created in D365FO based on the information received from VIES.
As Microsoft Flow can’t connect directly to SOAP services, we need to create a Logic Apps Custom Connector first. After creating the Logic Apps Custom Connector, we will create a Logic App which will run the custom connector.
After this we will create a Flow which will deliver and receive the information from the Logic App, then we will create a PowerApps which will provide the information to the Flow and finally we will integrate this PowerApps into Dynamics 365 for Finance and Operations.
At the end of this post, you should have a working PowerApps app. However, this post is for educational purposes so not everything will be optimized for actual production use. If you plan to use this app for production purposes it is at your own account.
Create Logic Apps Custom Connector
To create a Logic Apps connector you first must log in to the Azure Portal. In Azure click the create resource button. Search for “Logic Apps Custom Connector” and then click create.
Then fill in the required fields in the creation screen and press create. The creation will take a moment. When the creation has finished you will receive a notification, open the notification and click on go to resource.
In the Logic Apps Custom Connector (LACC) click on overview and then on edit. In the edit screen set the API endpoint to SOAP, the call mode SOAP to REST, import mode to WDSL File and click Import to select the file. The following files can be used:
- Production – http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl
- Test – http://ec.europa.eu/taxation_customs/vies/checkVatTestService.wsdl
The General information can be filled in as you like, but do not change the host or the scheme. When you are done click on the <security – next arrow>. Security should be no authentication so click the <definition – next arrow>.
In the definition you need to fill in a summary, this determines how the action of the connector is called in the Logic App, it does not matter too much what you fill in here as long as it is clear for you and your users.
The regular connector is the one you will be using most, the approx connector is for validating additional information (used for Spanish VAT for example). To switch to the other action, click on it. After you have finished the setup here, click on update connector to finish the connector.
Create Logic App
After creating the LACC we will create a Logic App to use this custom connector. Unfortunately, you can’t use Flow directly for this so you will have to use a Logic App as a middleman. From the Azure Portal click on Create a Resource and search for Logic App and click Create. Fill in the required fields in the screen, press create and wait for the notification that the app was created. Click on Go to resource to open the Logic App.
In the Logic App navigate to the Logic App designer and select <When a HTTP request is received>, alternatively click Blank Logic App and add the trigger When a <HTTP request is received>. In the HTTP Request Box, you have to fill in a JSON Schema. Unless you know what you are doing, use the schema below:
JSON Scheme:{
"type": "object",
"properties": {
"CountryCode": {
"mode": "Required",
"type": "string"
},
"vatNumber": {
"mode": "Required",
"type": "string"
},
"traderName": {
"mode": "Nullable",
"type": "string"
},
"traderCompanyType": {
"mode": "Nullable",
"type": "string"
},
"traderStreet": {
"mode": "Nullable",
"type": "string"
},
"traderPostcode": {
"mode": "Nullable",
"type": "string"
},
"traderCity": {
"mode": "Nullable",
"type": "string"
},
"requesterCountryCode": {
"mode": "Nullable",
"type": "string"
},
"requesterVatNumber": {
"mode": "Nullable",
"type": "string"
}
}
}
Click Next Step and search for your LACC. For this example, I will use the Input connector, but you can click the other connector if you want. After clicking on the connector, you will see a dropdown called Add new parameter, click it and add all parameters by clicking the checkmark.
Click the parameters and the dynamic content box should pop up and you should see the options from the previous step here. Map the correct steps to the input box. Continue by adding a new step and search for Response (request), add this step and add the body of the previous step to its body. See the screenshots below for the final setup.
Press Save and navigate back to the When a HTTP Request is received step and copy the HTTP Post URL. You will need this URL later.
Create a Microsoft Flow
A Microsoft Flow (Flow) always starts with a trigger, one or multiple actions and a result. It is a very flexible tool which can easily automate tasks for you as a user. To go to Flow navigate to the PowerApps website and sign in. When signed in go to Flows, click New and select Create from blank.
You will now see an overview screen, click Create from blank again and in the trigger screen search for PowerApps and double click the PowerApps trigger.
Click on New step and search for HTTP and add this as a step by double clicking. Set the Method to Post, add the URL from the Logic Apps Custom Connector and in the Body enter:
{
"CountryCode": <replace with Ask in PowerApps>,
"vatNumber":<replace with Ask in PowerApps>
}
Copy / pasting the parameters will not work so you will have to add them manually. There are (tedious) methods to rename the parameters however we will not look into these now. After adding the HTTP step which connects to our LACC, we expect a response. This response needs to be parsed before we can use it. To parse the response add the step Parse JSON. In the Content add the body from the HTTP.
Add the following schema to the Parse JSON step:
{
"type": "object",
"properties": {
"checkVatResponse": {
"type": "object",
"properties": {
"countryCode": {
"type": "string"
},
"vatNumber": {
"type": "string"
},
"requestDate": {
"type": "string"
},
"valid": {
"type": "boolean"
},
"name": {
"type": "string"
},
"address": {
"type": "string"
}
}
}
}
}
After parsing the results to a readable format, we need to respond the results back to PowerApps. To do this we need to add the Respond to PowerApps step and link the responses to the steps. All responses are treated as strings. Finally, Save the Flow and rename it to something useful.
Create a Microsoft PowerApps app – Initial setup
A PowerApps app is a tool which you can use to ask for input by a user and then process this input in various ways. In this example we will create an app which will upload a customer based on the retrieved VIES information.
To go to PowerApps you have to navigate to the PowerApps website and sign in. When Signed in go to Apps, click Create an App and select Canvas App. In the New App screen select Blank App and for this example I will select phone layout, but you can use tablet layout as well.
When the blank Power App has been created you can click on File and in the settings change the name and icon, so that the App is recognizable when saved and navigate to save and save the app. If you do not initially save the app, the autosave feature is not working and you could potentially lose all your work.
Create a Microsoft PowerApps app – Data Sources
In the menu screen click on connect to data and select the D365FO environment you would like to connect to, or if it is not listed click new connection. In the connection window you see the connections for this PowerApps app, if you have connected to D365FO before it will be listed here, otherwise click new connection.
In this window search the data source Dynamics 365 for Fin & Ops and click on it to create it. The environments you have access to will now be retrieved, find your environment and click on it. Now you will see all available data entities, select:
- CustomersV3, used to upload the customer back to D365FO
- CustomerGroups, used for the dropdown in selecting a customer group.
- LegalEntities, used for the dropdown in selecting a legal entity
- Currencies, used for the dropdown in selecting a currency
- AddressCountryRegions, used to convert the 2 letter ISO code to the 3 letter ISO code
- VATNumTables, used to upload the VAT number in the Sales Tax Exempt Number table
After selecting the data entities press connect. Unfortunately, the CustomerGroups data entity is set up to use the default company from the user account as their legal entity filter. *Edit* this is no longer true, read the bottom update to see the methods to achieve this.
If this is a problem for actual production use, you would have to create a new entity which includes the company filter as a separate field. Please be sure to set up a default company for your user, otherwise you will get no results.
After creating the data sources we will assign the earlier created flow to this PowerApp. To do this navigate to Actions, Flow and click on the specific Flow. Your data sources now should look like this.
Create a Microsoft PowerApps app – Naming convention
When creating a PowerApps app you will have a lot of controls on the screen in a short time. As you will often reference these controls it is advised to think of a naming convention for the controls.
For this demonstration I have selected <Control Subject>_<Control type> as my convention. To rename a control, select it and click on the name in the top right corner.
Create a Microsoft PowerApps app – Variables and Collections
To make the most use of the functionality of PowerApps we will be using variables and collections. Variables give you ease of use by assigning variables to (multiple) fields and on updates, you just have to worry about the variable instead of all the fields.
On top of this certain functions require you to use variables instead of direct references. A collection is like a variable, but where a variable is a single value, a collection represents a table.
A variable is created and updates via the Set(<variable name>,<variable value>) formula and the collection can be updated via multiple formulas but in our example I will be using ClearCollect(<collection name>,<collection reference>) which clears all the old values in the selection and overwrites them with the new referenced values. It is good practice to get a common naming for variables and collections, like VAR and COL.
Create a Microsoft PowerApps app – Controls
A PowerApps app is composed of types of controls, these are the actual things a user sees on the app. To add these types of controls, navigate to Insert and select the correct controls to see the related dropdown. For our app we will be using 5 types of controls:
- Labels, found under Insert, Text, Label. A Label is a piece of text you can define, which the user of your app can’t change.
- Text Input, found under Insert, Text, Text Input. A Text Input is a text box in which the user of your app can input text which you can then process in the PowerApp.
- Button, found under Insert, Controls, Button. A Button is a control that is clickable.
- Drop down, found under Insert, Controls, Drop Down. A Drop down is a list from which you can select values.
- Combo box, found under Insert, Controls, Combo box. A Combo Box is like a Drop Down with the difference that in a Combo Box you can type as well to speed up finding results.
A control’s properties can be freely defined via the properties tab and the advanced tab. Alternatively, you can also select the control and navigate to the formula bar at the top and select the control property you would like to edit. The text property defines the name the user sees on the screen.
A control’s property can have multiple formulas assigned; each formula is separated via a “;”. Information about the formulas can be found here.
Create a Microsoft PowerApps app – Export data to Dynamics 365 for Finance and Operations
To communicate the data back to D365FO we need to create Screens of the type Form. These screens are linked to a data source and the selected fields of the data source are displayed on the form. To submit the values of the form fields to D365FO the formula SubmitForm(<FormName>) is used.
For the InsertScreenCustomer this formula is bound to the Confirm button on the InputScreen and for the InsertScreenVAT this formula is bound to the next button on the HomeScreen.
To configure the data source, navigate to the form and click the data source dropdown under properties. Do not click on the add data source on the blank form, this creates a new data source. Select the data source you would like to use and click on add fields.
In here you can select the fields required. Each field has a field name and a display name, field names are unique and display names can overlap. When searching in the add fields form, PowerApps automatically searches both fields.
By default, the fields are in manual entry mode. However, in most cases you enter the data elsewhere in the PowerApps app. To overrule this, you will have to unlock the field by pressing the unlock icon and then overwrite the Default and Update values with whatever you would like them to be.
Although only the update value is required it is recommended to change the default value as well. So that you know what has been entered for that field should you run into an error.
Create a Microsoft PowerApps app – HomeScreen
I have designed my HomeScreen like this:
Below are the formulas assigned to the controls.
- App, this is the initial screen
- OnStart
Set(vatNumber,””);
Set(CountryCode,””);
Set(Results_Address,””);
Set(Results_Name,””);
Set(Results_Valid,””);
Set(Results_RequestDate,””);
Set(Results_vatNumber,””);
Set(Results_countryCode,””);
Set(CountryCodeImport,””);
Set(CountryConverted,””);
ClearCollect(CountryConvert,AddressCountryRegions);
Clear(ViesCheckResults);
Set(Next_ButtonDisplayMode,DisplayMode.Disabled);
Reset(vatNumber_Input);
Reset(Company_DropDown);
Reset(CustGroup_DropDown);
Reset(Currency_Dropdown);
Reset(CustAccount_Input);
NewForm(InsertFormCustomer);
NewForm(InsertFormVAT)
- vatNumber_Button
- OnSelect
Set(CountryCode ,Left(vatNumber_Input.Text,2));
Set(vatNumber, Right(vatNumber_Input.Text,
Len(vatNumber_Input.Text)-2));
ClearCollect(ViesCheckResults,
DM_ViesChecker_Flow.Run(CountryCode,vatNumber));
Set(Results_Address, First(ViesCheckResults).address);
Set(Results_countryCode, First(ViesCheckResults).countrycode);
Set(Results_Name, First(ViesCheckResults).name);
Set(Results_RequestDate, First(ViesCheckResults).requestdate);
Set(Results_Valid, First(ViesCheckResults).valid);
Set(Results_vatNumber, First(ViesCheckResults).vatnumber);
Set(CountryConverted,LookUp(CountryConvert,ISO =
Results_countryCode,’Country/region’));
If(Results_Valid = “True”,
Set(Next_ButtonDisplayMode,DisplayMode.Edit),
Set(Next_ButtonDisplayMode,DisplayMode.Disabled))
- Reset_Button
- OnSelect
Set(vatNumber,””);
Set(CountryCode,””);
Set(Results_Address,””);
Set(Results_Name,””);
Set(Results_Valid,””);
Set(Results_RequestDate,””);
Set(Results_vatNumber,””);
Set(Results_countryCode,””);
Set(CountryCodeImport,””);
Set(CountryConverted,””);
ClearCollect(CountryConvert,AddressCountryRegions);
Clear(ViesCheckResults);
Set(Next_ButtonDisplayMode,DisplayMode.Disabled);
Reset(vatNumber_Input);
Reset(Company_DropDown);
Reset(CustGroup_DropDown);
Reset(Currency_Dropdown);
Reset(CustAccount_Input);
NewForm(InsertFormCustomer);
NewForm(InsertFormVAT)
- Next_Button
- OnSelect
SubmitForm(InsertFormVAT);
Navigate(InputScreen,ScreenTransition.Fade)
- DisplayMode = Next_ButtonDisplayMode
- Company_DropDown
- Items = LegalEntities
- Value = Name
- Results_Name_Value (this is a Label control)
- Fill = RGBA(204, 204, 204, 1)
- Text = Results_Name
- Results_Address_Value (fill equal to results_name_value)
- Text = Results_Address
- Results_Country_Value (fill equal to results_name_value)
- Text = Results_countryCode
- Results_VATNo_Value (fill equal to results_name_value)
- Text = Results_vatNumber
- Results_Valid_Value (fill equal to results_name_value)
- Text = Results_Valid
Create a Microsoft PowerApps app – InputScreen
To add a new screen, you will have to click New Screen at the top left and select Blank.
I have designed my InputScreen like this:
In this screen the following controls have been added:
- CustGroup_Dropdown (items are filtered by the default legal entity the user is in, this is design of the data entity and can’t be changed. To overrule this you would have to create a new data entity)
- Items = CustomerGroups
- Value = Description
- CustAccount_Input (account number for the customer, can’t be empty. Always a manual entry regardless of Number Sequence settings. To overrule this you would have to move this control to the background and retrieve the next number in the number sequence from D365FO).
- Currency_Combobox
- Items = Currencies
- DisplayFields = [“CurrencyCode”]
- SearchFields = [“CurrencyCode”]
- Summary_Text (label)
- Text:
“Company: “&”
“&Company_DropDown.Selected.LegalEntityId&”
“&”Customer Name: “&”
“&Results_Name&”
“&”Customer Group: “&”
“&CustGroup_DropDown.Selected.’Customer group’&”
“&”Customer VAT: “&”
“&Results_countryCode&Results_vatNumber&”
“&”Customer Country: “&”
“&CountryConverted&”
“&”Currency: “&”
“&Currency_ComboBox.Selected.’Currency code’&”
“&”Customer Address: “&”
“&Results_Address
- Back_Button
- OnSelect = Navigate(HomeScreen,ScreenTransition.Fade)
- Confirm_Button
- OnSelect
SubmitForm(InsertFormCustomer);
Set(vatNumber,””);
Set(CountryCode,””);
Set(Results_Address,””);
Set(Results_Name,””);
Set(Results_Valid,””);
Set(Results_RequestDate,””);
Set(Results_vatNumber,””);
Set(Results_countryCode,””);
Set(CountryCodeImport,””);
Set(CountryConverted,””);
ClearCollect(CountryConvert,AddressCountryRegions);
Clear(ViesCheckResults);
Set(Next_ButtonDisplayMode,DisplayMode.Disabled);
Reset(vatNumber_Input);
Reset(Company_DropDown);
Reset(CustGroup_DropDown);
Reset(Currency_ComboBox);
Reset(CustAccount_Input);
NewForm(InsertFormCustomer);
NewForm(InsertFormVAT);
Navigate(HomeScreen,ScreenTransition.Fade)
Create a Microsoft PowerApps app – InsertScreenCustomer
For this form the data source CustomersV3 was selected.
The following fields have been added and the default and update fields were changed to:
- dataAreaId = Company_DropDown.Selected.LegalEntityId
- CustomerGroupId = CustGroup_DropDown.Selected.’Customer group’
- OrganizationName = Results_Name
- CustomerAccount = CustAccount_Input.Text
- SalesCurrencyCode = Currency_ComboBox.Selected.’Currency code’
- AddressCountryRegionId = CountryConverted
- TaxExemptNumber = Results_countryCode&Results_vatNumber
- AddressStreet = Results_Address
Please note that the field names above are the actual field names and not the display names.
Create a Microsoft PowerApps app – InsertScreenVAT
For this form the data source VATNumTables was selected.
The following fields have been added and the default and update fields were changed to:
- dataAreaId = Company_DropDown.Selected.LegalEntityId
- Name = Results_Name
- CountryRegionId = CountryConverted
- VATNum = Results_countryCode&Results_vatNumber
Please note that the field names above are the actual field names and not the display names.
Create a Microsoft PowerApps app – App ID
The PowerApp should now be fully configured. To finish the setup, go to File and click Save. After you have saved the app you can publish it.
After the App has been published navigate back to the PowerApps portal. Navigate to your App and click the … icon and select Details. In the Details screen note down the app id or copy it to your clipboard.
Adding the PowerApps app to Dynamics 365 for Finance and Operations
In D365FO you can add a PowerApp via two ways, as a dropdown in a view or in a workspace. After clicking the button the follow up steps are the same, so we will focus on adding the App to a workspace.
To add an App to a workspace you have to personalize the workspace, then click on the … and click on add a PowerApp next click on the screen where you want the App to land.
Fill in the form, add the name, app id, keep the input data dropdown empty, the application size can be set to thin and the legal entity access to all legal entities (this is the default setting, it can happen that the insert form bugs out when you open the Legal entity dropdown, if this is the case just keep it closed and insert the app).
App Demo in Dynamics 365 for Finance and Operations
Reference data from VIES website, this step is for reference purposes only and not required for the app functionality.
VAT Number entered in the HomeScreen from within D365FO, note that the Next button is disabled.
Pressing the Check VAT button retrieves the information from VIES. As the VAT Number is Valid the Next button is enabled.
In the next screen we can enter additional customer information as per setup of our app and we can confirm our entry which sends the data to D365FO. Please note that the app automatically resets after confirming.
In the customer table the customer has been created. The name, address, customer group and VAT number have been entered automatically based on the information received from VIES.
Conclusion
In this post we have setup a Logic App Custom Connector, a Logic Apps app, a Microsoft Flow a PowerApps app and we integrated the PowerApps app into Dynamics 365 for Finance and Operations.
Per setup we walked through the required settings. You now should be able to setup a similar functionality for your own purposes. Besides this, I hope this post has helped you understand the ways you can use and leverage the different tools in the Dynamics platform, Power platform and Azure platform to facilitate the needs of your organization or your customers.
Update regarding company restricted data entities
With PowerApps it is not possible to load all the data in the CustomerGroups data entity, because the parameter cross-company defaults to no. The parameter itself can be manually tested by going to your environment and load the data entity manually via the URL:
https://<yourenvironment>.dynamics.com/data/CustomerGroups?cross-company=trueFrom within PowerApps this is however not possible to change, since you can only load the data entities with their default settings. However, you can achieve this via Microsoft Flow. For this example, we will be creating the Flow and integrate it into PowerApps to achieve this.
First, we will create a new Flow the first step will be PowerApps. After this we will search for the action Dynamics 365 for Fin & Ops, click on it and select the action List Items present in a table. Open the advanced options and enter your instance URL, select the data entity CustomerGroups and set Cross Company to Yes.
This will query the data entity CustomerGroups with the Cross Company filter set to Yes, the results will be the entire data entity in JSON format. In our earlier Flow we parsed the response and set the response to Respond to PowerApps. This is fine for single record responses, however in this case we will be receiving back an array. Since this is the case, we will be using the Response action. The status can be left at the default 200 value, leave the headers empty, set the Body to Value and in the Response Body JSON Schema set the following schema:
{
"type": "array",
"items": {
"type": "object",
"properties": {
"@@odata.etag": {
"type": "string"
},
"ItemInternalId": {
"type": "string"
},
"dataAreaId": {
"type": "string"
},
"CustomerGroupId": {
"type": "string"
},
"ClearingPeriodPaymentTermName": {
"type": "string"
},
"DefaultDimensionDisplayValue": {
"type": "string"
},
"CustomerAccountNumberSequence": {
"type": "string"
},
"IsSalesTaxIncludedInPrice": {
"type": "string"
},
"Description": {
"type": "string"
},
"WriteOffReason": {
"type": "string"
},
"PaymentTermId": {
"type": "string"
},
"TaxGroupId": {
"type": "string"
}
}
}
}
The result should look like this below.
Now that the Flow is complete, we will integrate it into PowerApps, click on the Action menu and click on Flow and then click on your CustomerGroups flow to activate it in your PowerApp. After this Add the formula below to the Reset Button (On Select) and the App (OnStart).
ClearCollect(CustomerGroupsFlow,DM_CustGroupsLoad.Run());
After this modify the current Customer Group drop down and set the Items to:
Filter(CustomerGroupsFlow,Lower(dataAreaId) =Lower(Company_DropDown.Selected.LegalEntityId))The lower formula is needed since the filter formula is case sensitive, the dataAeaId is delivered in lower case letters and the LegalEntityId is delivered in capital letters. Although you don’t need the double Lower formula, it easier to include it to prevent errors in capital letter mismatches.
Last thing to do is to change the fields relying on the CustGroup_Dropdown. The following need to be changed:
- InputScreen, CustGroup_Dropdown, field Value = Description
- InputScreen, Summary_Text, field Text = CustGroup_DropDown.Selected.CustomerGroupId
- InsertScreenCustomer, InsertFormCustomer, field Customer Group, fields Default and Update = CustGroup_DropDown.Selected.CustomerGroupId
If setup correctly you should have the following results.