How to Automatically Set The Opportunity Currency in Dynamics 365 Sales

In this blog post, I’ll show you how to create a solution in Dynamics 365 that automatically ensures the Opportunity currency matches the Account currency.

I wrote this solution as I got so frustrated that when you create an opportunity in Dynamics 365 Sales, that the currency is not automatically set to the correct currency. Instead it goes to the default currency as set in the system, which will create all sort of problems when you are working in a multi region sales team. (selection of wrong currencies, quote then cannot use the correct currency, etc)

This solution will use JavaScript to retrieve and compare these values, and if they don’t match, update the Opportunity currency to reflect the Account’s currency. Additionally, we’ll publish this solution and configure it to run seamlessly within Dynamics 365.

Prerequisites

Before you begin, ensure you have the following:

  • Administrator access to Dynamics 365.
  • Basic understanding of JavaScript and Dynamics 365 customization.

Let’s break down the process step-by-step.

Step 1: Create a New Solution in Dynamics 365

The first step is to create a solution to contain your custom JavaScript logic and publish it into Dynamics.

  1. Navigate to Power Platform Admin Center:
    • Go to your Dynamics 365 environment.
    • Click on the gear icon and select Advanced Settings.
    • In the settings area, click on Solutions.
  2. Create a New Solution:
    • Click New to create a new solution.
    • Enter details such as:
      • Display Name: Opportunity-Account Currency Sync.
      • Publisher: Select or create a new one.
      • Version: Start with 1.0.0.0.
  3. Add the Opportunity Entity to the Solution:
    • In the solution editor, click on Add ExistingEntityOpportunity.
    • This allows us to add custom logic to the Opportunity entity form.

Step 2: Write the JavaScript for Currency Sync

Next, we’ll write the JavaScript code to compare the Opportunity and Account currency and update the Opportunity currency if they don’t match.

  1. Create a Web Resource for JavaScript:
    • In the solution, navigate to Web Resources and click New.
    • Select JavaScript (JScript) as the type, and name it currencySync.js.
    • Paste the following JavaScript code into the web resource:
    • function getDetailsFromOpportunity(executionContext) {
      var formContext = executionContext.getFormContext();
      
      // Check if the Opportunity has been saved (i.e., it has an ID)
      var opportunityId = formContext.data.entity.getId();
      if (!opportunityId) {
      console.log("This is a new opportunity. The record has not been saved yet.");
      return; // Exit the function if it's a new, unsaved Opportunity
      }
      
      // Proceed with the currency check if the Opportunity is not new
      opportunityId = opportunityId.replace("{", "").replace("}", "");
      
      // Get the Account (Customer Field) from the Opportunity
      var accountLookup = formContext.getAttribute("parentaccountid"); 
      if (accountLookup != null && accountLookup.getValue() != null) {
      var account = accountLookup.getValue()[0]; 
      var accountId = account.id;
      
      // Retrieve the statuscode and compare currencies only if the opportunity is open
      Xrm.WebApi.retrieveRecord("opportunity", opportunityId, "?$select=statuscode").then(
      function success(result) {
      var opportunityStatus = result.statuscode; 
      if (opportunityStatus === 1) { 
      console.log("Opportunity is open. Proceeding with currency check.");
      
      // Retrieve the currency from the related Account
      Xrm.WebApi.retrieveRecord("account", accountId, "?$select=transactioncurrencyid&$expand=transactioncurrencyid($select=currencyname)").then(
      function success(result) {
      if (result.transactioncurrencyid != null) {
      var accountCurrencyId = result.transactioncurrencyid.transactioncurrencyid.toLowerCase(); 
      
      // Get the Currency field from the Opportunity
      var opportunityCurrencyLookup = formContext.getAttribute("transactioncurrencyid"); 
      if (opportunityCurrencyLookup != null && opportunityCurrencyLookup.getValue() != null) {
      var opportunityCurrency = opportunityCurrencyLookup.getValue()[0]; 
      var opportunityCurrencyId = opportunityCurrency.id.replace("{", "").replace("}", "").toLowerCase(); 
      var opportunityCurrencyName = opportunityCurrency.name; 
      console.log("Opportunity Currency Name: " + opportunityCurrencyName + " | Currency Id: " + opportunityCurrencyId);
      
      // Compare the Opportunity currency with the Account currency
      if (accountCurrencyId !== opportunityCurrencyId) {
      console.log("Currencies do not match. Updating Opportunity currency to match Account currency.");
      
      // Update the Opportunity currency to match the Account currency
      formContext.getAttribute("transactioncurrencyid").setValue([{
      id: accountCurrencyId, 
      name: result.transactioncurrencyid.currencyname, 
      entityType: "transactioncurrency"
      }]);
      
      // Save the form after the currency is updated
      formContext.data.entity.save();
      } else {
      console.log("Currencies match. No update required.");
      }
      } else {
      console.log("No currency is associated with this opportunity.");
      }
      }
      },
      function(error) {
      console.log("Error retrieving account currency: " + error.message);
      }
      );
      } else {
      console.log("Opportunity is not open. No currency update will be performed.");
      }
      },
      function(error) {
      console.log("Error retrieving opportunity status: " + error.message);
      }
      );
      } else {
      console.log("No account is associated with this opportunity.");
      }
      }
  2. Save and Publish the Web Resource:
    • Click Save and then Publish the web resource.

Step 3 : Add the JavaScript to the Opportunity Form for the Account Field onChange Event

In addition to loading the script when the form is loaded, we’ll also trigger it when the Account field is changed by the user.

1. Go to the Opportunity Form Editor:

  • In the solution editor, select the Opportunity entity, and click on Forms.
  • Open the Main form for editing.

2. Add the JavaScript Web Resource to the Form (if not already added):

  • If you’ve already added the currencySync.js web resource in the previous steps, you don’t need to do this again.
  • If not, click on Form PropertiesForm LibrariesAdd, and select the currencySync.js web resource.

3. Attach the Function to the Form Load Event (if not already done):

  • In the Event Handlers section under Form Properties, add the function as before for the OnLoad event.
  • Make sure to set the correct event handler details:
  • Do the same for On Save, so when the opportunity is saved, the function will check if the currency needs to be updated.

4. Attach the Function to the Account Field onChange Event:

  • In the Form Editor, locate the Account field (which is the parentaccountid field in Dynamics).
  • Double-click on the Account field, or select it and click Change Properties.
  • Go to the Events tab of the field properties.
  • Under Field Events, click Add.
  • In the Library dropdown, select the currencySync.js library (if not already added).
  • In the Function Name field, enter getDetailsFromOpportunity (the same function name as used for the onLoad event).
  • Uncheck the box that says “Pass execution context as the first parameter,” if it’s checked.
  • Click OK to save the event handler for the Account field’s onChange event.

5. Save and Publish the Form:

  • Save the changes made in the form editor.
  • Click Publish to make the changes live in Dynamics 365.

Testing the onChange Event

Now, your JavaScript function will be triggered both when the Opportunity form loads and when the Account field is changed.

Test the Functionality:

  1. Open an Opportunity in Dynamics 365.
  2. Change the Account value, and ensure that the script compares the Opportunity currency with the new Account currency.
  3. If the currencies don’t match, the Opportunity currency should update automatically.

Have any questions on this script, or happy that it worked for you? Leave a comment below!

AccessOrange is a leading Microsoft Partner that specializes in Microsoft 365, Dynamics 365 and Azure to help our customers work smarter.
If you need help with building this solution in your own environment, leave your contact information below, and we will contact you as soon as possible.

"*" indicates required fields

This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
This field is for validation purposes and should be left unchanged.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply

Your email address will not be published. Required fields are marked *