Skip to main content

Notifications

Announcements

No record found.

Microsoft Dynamics 365 | Integration, Dataverse...
Answered

WEB-API Request to create a quote based on an opportunity

(0) ShareShare
ReportReport
Posted on by 10

HI everbody,

I am trying to find what I need in a web request so that I can create a fresh quote based on an existing opportunity.
The goal is to have several information taken from the opportunity into the quote (like Account, Contact, Currency, ...)

There is an SDK - I know - but I need a way to do this without the SDK. For testing purposes I am using Postman.

Here is the Request that I am currently using:

URL:


POST {{URLTOCRM/api/data/v9.1/quotes?$select=quoteid}}

BODY:

{
    "quotenumber": "ZYY-Q21-00141",
    "totalamount": 0,
    "opportunityid@odata.bind": "/opportunities(71dfe9e9-a3ee-eb11-bacb-0022487ef2a3)"
}
 
As a result I get a new quote that has the opportunity linked. But no other information was transfered from the opportunity to the quote:
pastedimage1627381218008v1.png

  • Jeo Profile Picture
    Jeo 10 on at
    RE: WEB-API Request to create a quote based on an opportunity

    Excellent answer, everything works as expected. I does exactly what I was looking for. Thank you again!

  • meelamri Profile Picture
    meelamri 13,206 User Group Leader on at
    RE: WEB-API Request to create a quote based on an opportunity

    Don't hesitate to give feedback if it doesn't work on your environment, good luck !

  • Jeo Profile Picture
    Jeo 10 on at
    RE: WEB-API Request to create a quote based on an opportunity

    I'll try that. It looks exactly like what I was hoping for

  • Verified answer
    meelamri Profile Picture
    meelamri 13,206 User Group Leader on at
    RE: WEB-API Request to create a quote based on an opportunity

    Hi, 

    You can use the standard action: "GenerateQuoteFromOpportunity": https://docs.microsoft.com/en-us/dynamics365/customer-engagement/web-api/generatequotefromopportunity?view=dynamics-ce-odata-9

    This action has a parameter that allows you to define the columns to copy from the opportunity. Please refer to my sample code below: 

     

    var parameters = {};
    parameters.OpportunityId = "289756E6-F2EA-EB11-BACB-000D3A4AF872";
    //allColumns...
    parameters.ColumnSet = {
            "AllColumns": true
    }
    
    var req = new XMLHttpRequest();
    req.open("POST", Xrm.Page.context.getClientUrl()   "/api/data/v9.1/GenerateQuoteFromOpportunity", true);
    req.setRequestHeader("OData-MaxVersion", "4.0");
    req.setRequestHeader("OData-Version", "4.0");
    req.setRequestHeader("Accept", "application/json");
    req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
    req.onreadystatechange = function() {
        if (this.readyState === 4) {
            req.onreadystatechange = null;
            if (this.status === 200) {
                var results = JSON.parse(this.response);
            } else {
                Xrm.Utility.alertDialog(this.statusText);
            }
        }
    };
    req.send(JSON.stringify(parameters));

  • Sergi Valero Profile Picture
    Sergi Valero 145 on at
    RE: WEB-API Request to create a quote based on an opportunity

    Hey Jeo!

    Not 100% sure there isn't an easier way to do it. The easiest way I know and how I always do this is by creating a web resource, passing the execution context and work from there with the Web API.

  • Jeo Profile Picture
    Jeo 10 on at
    RE: WEB-API Request to create a quote based on an opportunity

    Thank you. So there is no easy way to just say "here is the opportunity, please get all the info from there" like you can do using the frontend ?!

    Many thanks for the detailed answer. It is solvable like that I think. I just thought there would be an easier way.

  • Verified answer
    Sergi Valero Profile Picture
    Sergi Valero 145 on at
    RE: WEB-API Request to create a quote based on an opportunity

    Hello Jeo!!

    In order to add more information to your new quote, you need to add the other properties into the body of your request.

    If you want to add the account and contact associated with your opportunity, you need to indicate the account id and contact id. If your opportunity is already linked to the opportunity, you can simply get the values from there through the executionContext of the opportunity (not sure you can get them using Postman), here is an example:

    Postman Body: 

    {
        "quotenumber": "ZYY-Q21-00141",
        "totalamount": 0,
        "opportunityid@odata.bind": "/opportunities(71dfe9e9-a3ee-eb11-bacb-0022487ef2a3)"
        "customerid@odata.bind": "/accounts(accountid)"
    }
     Where accountid is the id of the associated account.

    Javascript web resource:

    function createQuote (executionContext) {
        const formContext = executionContext.getFormContext();
        const opportunityId = formContext.data.entity.getId().slice(1,-1);
        const accountId = formContext.getAttribute(accountField).getValue();
        const contactId = formContext.getAttribute(contactField).getValue();
        
        const parameters = {
            quotenumber: "ZYY-Q21-00141",
            totalamount: 0,
            opportunityid@odata.bind: "/opportunities("   opportunityId   ")",
            accountid@odata.bind: "/accounts("   accountId   ")",
            contactid@odata.bind: "/contacts("   contactId   ")"
        }
        Request("POST", formContext.context.getClientUrl()   '/api/data/v9.2/quotes', parameters);
    }
    
    function Request (action, uri, parameters) {
        const data = parameters || {};
        return new Promise(function (resolve, reject) {  
            var request = new XMLHttpRequest();   
            request.open(action, uri, true);  
            request.setRequestHeader("OData-MaxVersion", "4.0");  
            request.setRequestHeader("OData-Version", "4.0");  
            request.setRequestHeader("Accept", "application/json");  
            request.setRequestHeader("Content-Type", "application/json; charset=utf-8");  
            request.setRequestHeader("Prefer", "odata.maxpagesize=100");  
     
            request.onreadystatechange = function () {  
                if (this.readyState === 4) {  
                    request.onreadystatechange = null;  
                    switch (this.status) {  
                        case 200: // Success with content returned in response body.  
                        case 204: // Success with no content returned in response body.  
                            resolve(this);  
                            break;  
                        default: // All other statuses are unexpected so are treated like errors.  
                            var error;  
                            try {  
                                error = JSON.parse(request.response).error;  
                            } catch (e) {  
                                error = new Error("Unexpected Error");  
                            }  
                            reject(error);  
                            break;  
                    }  
                }  
            };  
            request.send(JSON.stringify(data));  
        });
    }

    Note that the fields' name I used are an example, make sure to replace them with the name of your fields before using the code

    For additional information:

    MS Dataverse Web API

    Request Function Source

    @odata.bind documentation

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Congratulations 2024 Spotlight Honorees!

Kudos to all of our 2024 community stars! 🎉

Meet the Top 10 leaders for December!

Congratulations to our December super stars! 🥳

Get Started Blogging in the Community

Hosted or syndicated blogging is available! ✍️

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 291,642 Super User 2024 Season 2

#2
Martin Dráb Profile Picture

Martin Dráb 230,371 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Product updates

Dynamics 365 release plans