cancel
Showing results for 
Search instead for 
Did you mean: 
Reply
Highlighted
Frequent Visitor

attributeOnChange retriveRecord and updateRecord

I need some help putting together some js to update Price List (pricelevelid) on a Quote if the Potential Customer (customerid) is changed.

 

I am able to look up the appropriate pricelevelid using this code:

 

 

function () {
    this.attributeOnChange = function () 
	{
				
		if (Xrm.Page.getAttribute("customerid").getValue() != null && Xrm.Page.getAttribute("customerid").getValue()[0].id != null) {
		var accountid = Xrm.Page.getAttribute("customerid").getValue()[0].id;

		
			Xrm.WebApi.retrieveRecord("account", accountid, "?$select=name,&$expand=defaultpricelevelid($select=pricelevelid,name)").then(
				function success(result) {
							
					???
				
				}
			);   
			
		}
		
	}    
}

 

 

I am unclear on how to use updateRecord to update the lookup field with schema name  pricelevelid in the Quote entity using the data retrieved using Xrm.WebApi.retrieveRecord.

 

Any help is appreciated!

1 ACCEPTED SOLUTION

Accepted Solutions
Highlighted
Super User II
Super User II

Re: attributeOnChange retriveRecord and updateRecord

Just to confirm your requirements, on which entity is the customer changing to update the price list of all its quotes?

There a few things that seems to need fixing.

  1. Your function is not registered properly to the on change event of the field. The simplest way for you to register to the on change event is: 
    1. In the form design in classic mode, add your JavaScript file to the form.
    2. Select the field and click on "Change Properties" in the ribbon, select the "Events" tab
    3. Click "Add" to add your function to trigger:
      2020-09-14_10-02-42.png
    4. Select the right JavaScript file (if you have more than one on the form) and enter your JavaScript function name without the () and parameters. Check "Pass execution context as first parameter" option.
      2020-09-14_10-04-19.png
    5. Save and close all and publish all your changes.

  2. Here's update sample JavaScript function:
    1. First, it gets the price list ID from the newly selected account
    2. Then it retrieves all the quotes related to the newly selected account
    3. Finally it updates the quotes with the account's price list ID

 

function OnCustomerChange (executionContext) 
{
    var formContext = executionContext.getFormContext();
    if (formContext.getAttribute("customerid").getValue() != null && formContext.getAttribute("customerid").getValue()[0].id != null) 
    {
        let accountid = formContext.getAttribute("customerid").getValue()[0].id;
        
        //1) get the price list ID from the account
        Xrm.WebApi.retrieveRecord("account", accountid, "?$select=_defaultpricelevelid_value").then(
            function success(account) {
                const query = `?$select=quoteid&$filter=_customerid_value eq '${accountid}'`;

                var pricelist = new Array();
                pricelist[0] = new Object();
                pricelist[0].entityType = "pricelevel";
                pricelist[0].id = account._defaultpricelevelid_value;
                pricelist[0].name = "Updated Price List";
                formContext.getAttribute("pricelevelid").setValue(pricelist);

                //2) get the quotes from the account
                Xrm.WebApi.retrieveMultipleRecords("quote", query).then(
                    function success(quotes) {
                        for (let i = 0; i < quotes.entities.length; i++) 
                        {
                            //3) update the quotes
                            let data = { "pricelevelid@odata.bind": `/pricelevels(${account._defaultpricelevelid_value})` };
                            Xrm.WebApi.updateRecord("quote", quotes.entities[i].quoteid, data).then(
                                function success() { });
                        }
                    });            
            }, function error() {
                console.log("User selected a contact");
            });
    }
}

 

Note: I also used the formContext

Hope this helps...

View solution in original post

10 REPLIES 10
Highlighted
Super User II
Super User II

Re: attributeOnChange retriveRecord and updateRecord

Hi @CraigK,

Here's a sample of the update code. It's getting all the quotes related to the accountId then for each quote, sets the new price list id (pricelevelid). Hope this helps!

 

 

 

const query = `?$select=quoteid&$filter=_customerid_value eq '${accountid}'`
let result = Xrm.WebApi.retrieveMultipleRecords("quote", query).then(
function success(result) {
   for (let i = 0; i < result.entities.length; i++) {
    let data = { "pricelevelid": newPriceListId };
    Xrm.WebApi.updateRecord("quote", result.entities[0].quoteid, data).then(
        function success() { });
   }
});

 

 

 

BTW Xrm.Page is deprecated. You should use the formContext (executionContext.getFormContext()). More info: https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/clientapi-form-cont...

Highlighted
Frequent Visitor

Re: attributeOnChange retriveRecord and updateRecord

@EricRegnier Thanks for the reply.

 

From what I can tell with my limited experience this code should work if the accountid variable is defined, but I can't seem to get this working with the Xrm.Page or formContext objects.

 

The js isn't producing an error so it's a bit difficult for me to troubleshoot.  Not entirely sure where to proceed from here.  Do you have any suggestions on what I might look at to debug this?

 

Thanks again for your help and any suggestions you might have!

Highlighted
Super User II
Super User II

Re: attributeOnChange retriveRecord and updateRecord

The accountid comes from the outer code from your example: "var accountid = Xrm.Page.getAttribute("customerid").getValue()[0].id;"

 

For formContext, you need to have a param for the executionContext in your function for it and CDS will pass it:
this.attributeOnChange = function (executionContext)

 

Can you share your whole code? It would help to debug. Cheers!

Highlighted
Frequent Visitor

Re: attributeOnChange retriveRecord and updateRecord

@EricRegnier This is the code I have in place for the web resource being called by the form.  I'm afraid I'm not strong in Javascript so debugging is challenging for me.

 

function () 
	{
		this.attributeOnChange = function () 
		{
			if (Xrm.Page.getAttribute("customerid").getValue() != null && Xrm.Page.getAttribute("customerid").getValue()[0].id != null) 
			{
				var accountid = Xrm.Page.getAttribute("customerid").getValue()[0].id;
									
				const query = `?$select=quoteid&$filter=_customerid_value eq '${accountid}'`
				let result = Xrm.WebApi.retrieveMultipleRecords("quote", query).then(
				function success(result) 
				{
					for (let i = 0; i < result.entities.length; i++) 
					{
						let data = { "pricelevelid": newPriceListId };
						Xrm.WebApi.updateRecord("quote", result.entities[0].quoteid, data).then(
						function success() { });
					}
				});
			}
		}    
	}

 

Highlighted
Super User II
Super User II

Re: attributeOnChange retriveRecord and updateRecord

Just to confirm your requirements, on which entity is the customer changing to update the price list of all its quotes?

There a few things that seems to need fixing.

  1. Your function is not registered properly to the on change event of the field. The simplest way for you to register to the on change event is: 
    1. In the form design in classic mode, add your JavaScript file to the form.
    2. Select the field and click on "Change Properties" in the ribbon, select the "Events" tab
    3. Click "Add" to add your function to trigger:
      2020-09-14_10-02-42.png
    4. Select the right JavaScript file (if you have more than one on the form) and enter your JavaScript function name without the () and parameters. Check "Pass execution context as first parameter" option.
      2020-09-14_10-04-19.png
    5. Save and close all and publish all your changes.

  2. Here's update sample JavaScript function:
    1. First, it gets the price list ID from the newly selected account
    2. Then it retrieves all the quotes related to the newly selected account
    3. Finally it updates the quotes with the account's price list ID

 

function OnCustomerChange (executionContext) 
{
    var formContext = executionContext.getFormContext();
    if (formContext.getAttribute("customerid").getValue() != null && formContext.getAttribute("customerid").getValue()[0].id != null) 
    {
        let accountid = formContext.getAttribute("customerid").getValue()[0].id;
        
        //1) get the price list ID from the account
        Xrm.WebApi.retrieveRecord("account", accountid, "?$select=_defaultpricelevelid_value").then(
            function success(account) {
                const query = `?$select=quoteid&$filter=_customerid_value eq '${accountid}'`;

                var pricelist = new Array();
                pricelist[0] = new Object();
                pricelist[0].entityType = "pricelevel";
                pricelist[0].id = account._defaultpricelevelid_value;
                pricelist[0].name = "Updated Price List";
                formContext.getAttribute("pricelevelid").setValue(pricelist);

                //2) get the quotes from the account
                Xrm.WebApi.retrieveMultipleRecords("quote", query).then(
                    function success(quotes) {
                        for (let i = 0; i < quotes.entities.length; i++) 
                        {
                            //3) update the quotes
                            let data = { "pricelevelid@odata.bind": `/pricelevels(${account._defaultpricelevelid_value})` };
                            Xrm.WebApi.updateRecord("quote", quotes.entities[i].quoteid, data).then(
                                function success() { });
                        }
                    });            
            }, function error() {
                console.log("User selected a contact");
            });
    }
}

 

Note: I also used the formContext

Hope this helps...

View solution in original post

Highlighted
Frequent Visitor

Re: attributeOnChange retriveRecord and updateRecord

@EricRegnier The Potential Customer (customerid) would change on the quote entity.  The original requirement was to change the price level on the individual quote but changing the price level on all open quotes is useful.

 

I have updated, saved and published the js file:

CraigK_2-1600096928525.png

 

I think I've registered the function properly to the OnChange event of the Potential Customer field then saved and published the form. 

 

CraigK_3-1600097340461.png

 

Changing the Potential Customer field is resulting in a script error:

 

CraigK_5-1600097912513.png

 

This has me confused because I think I have everything configured properly.

Highlighted
Solution Sage
Solution Sage

Re: attributeOnChange retriveRecord and updateRecord

2 things -

 

1) that error message usually appears when the Javascript is invalid in some way - say a missing { or a typo somewhere in the Javascript library. When I see those sort of errors I usually paste the code into Visual Studio Code or http://beautifytools.com/javascript-validator.php to identify where the error is.

 

2) Once you've fixed the library, you need to check the Pass Execution context as first parameter checkbox when you set up the Event Handler (@EricRegnier missed it off his screenshots).

 

 

---
If this post has answered your question please consider it for "Accept as Solution" or if it has been helpful give it a "Thumbs Up".
Highlighted
Super User II
Super User II

Re: attributeOnChange retriveRecord and updateRecord

Make sure there's no copy paste errors with special characters. I forgot to mention to check the "Pass execution context as first parameter" like Ben said.

2020-09-14_10-04-19.png

Which browser are you using? The script will only be compatible with ES6 browsers like version of Chrome, Edge, FireFox, not IE.

Highlighted
Frequent Visitor

Re: attributeOnChange retriveRecord and updateRecord

Thanks all.  I appreciate the link to the js validator and have bookmarked that reference.

 

The js validator indicates a missing semicolon on line 11.  Adding it to the end of the line did not resolve the error.

 

                const query = `?$select=quoteid&$filter=_customerid_value eq '${accountid}'`

 

 
 
 
 

Clipboard01.png

 

I also pasted the code to Notepad++ without seeing any obvious (to my untrained eye) errors. 

 

The option to pass execution context as first parameter has been checked.

I am using Edge 85.0.564.51.

Helpful resources

Announcements
Community Conference

Power Platform Community Conference

Find your favorite faces from the community presenting at the Power Platform Community Conference!

Watch Now

Experience what’s next for Power Apps

See the latest Power Apps innovations, updates, and demos from the Microsoft Business Applications Launch Event.

Power Platform ISV Studio

Power Platform ISV Studio

ISV Studio is designed to become the go-to Power Platform destination for ISV’s to monitor & manage published applications.

secondImage

Power Platform 2020 release wave 2 plan

Features releasing from October 2020 through March 2021

Users online (7,729)