Developer Resources
Create Quote & Create Order Gl...
Overview: Create Quote & Create Order Global Methods
18 min
the nue quote api suite nue on salesforce exposes a suite of apex global methods under ruby globalquoteserviceapi and ruby globalorderserviceapi that allow you to programmatically create fully priced quotes and orders — with the same pricing fidelity as the nue ui these methods are part of the broader https //docs nue io/apex global methods and services surface, which also includes services for recalculation, price tag reapplication, order generation, change orders, and more the quote apis include create a new business quote ( ruby globalquoteserviceapi createquote ) — the comprehensive method documented in this guide it supports both preview and commit modes preview mode allows users or integrated ai systems to simulate quote creation, verifying structure and pricing without persisting any data commit mode finalizes the quote as an official record the method handles the full lifecycle product resolution, bundle expansion, pricing engine execution, discount propagation, price tag evaluation, and optional database persistence — all in a single call create a new business order ( ruby globalorderserviceapi createorder ) — the order side equivalent, creating orders directly without going through the quote to order conversion flow these global methods sit alongside other quote and order services you may use in your workflow true 220,220,222 left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type note on scope while createquote and createorder are robust for initiating quotes/orders — adding products and performing pricing calculations — they are specifically engineered for the initial creation of quotes and orders for more intricate modifications after creation, such as detailed line item adjustments, advanced discounting changes, or complex product reconfigurations, the line editor remains the designated tool the line editor offers granular control for fine tuning quotes beyond the scope of these api methods design philosophy semantic rich, not line by line the create quote method is not a low level "insert a quotelineitem" api it is a semantic rich global method designed so that creating a quote via apex is as intuitive as creating one through the nue ui you describe what you want — products, quantities, terms, discounts — and the pricing engine handles everything else product resolution — find products by sku or name, resolve the correct https //docs nue io/price books based on https //docs nue io/unit of measures uoms , currency, and https //docs nue io/multi attribute pricing bundle expansion — automatically include https //docs nue io/product bundle items, auto populate required add ons, resolve https //docs nue io/dynamic product options pricing engine execution — calculate the full pricing formula chain (list price → system discount → subtotal → discretionary discount → total price → tax) discount propagation — apply header level discounts to all undiscounted lines, propagate parent level discounts to children, respect explicit overrides price tag evaluation — evaluate tiered, volume, and ramp https //docs nue io/price and discount tags ; apply auto attached tags from product configuration pricing attribute matching — auto resolve https //docs nue io/multi attribute pricing price book entries from account fields (e g , account type), match https //docs nue io/manage custom attributes in price book entries https //docs nue io/quantity tier attributes for price tags — dynamically resolve discount tiers based on field values (e g , account numberofemployees) validation — enforce business rules and return structured error messages with specific error codes built for ai integration a key design consideration for these apis is the emphasis on extensive and detailed warning and error messages this is critical given the intention for ai systems to utilize these methods for automated quote creation and management by providing highly detailed and comprehensive messages — with specific error codes, affected field names, and actionable descriptions — ai systems can comprehend outcomes — interpret whether a quote succeeded, partially succeeded with warnings, or failed with specific validation errors self correct — use error codes to automatically adjust inputs (e g , fix an invalid billing period, resolve a missing product sku) flag issues efficiently — surface warnings about discount precedence, duplicate price tags, or default values to human reviewers minimize manual intervention — improve accuracy and reliability of automated quote workflows the response always includes status "succeed" or "failure" — unambiguous outcome errors\[] structured error messages with errorcode , errortype , and human readable message warnings\[] non fatal messages (e g , product discount overrides header , duplicate price tag ) — present even on success data the fully priced quote with all line items, applied price tags, and calculated fields how it works create quote api flow key concepts preview vs commit every request includes an iscommit flag iscommit = false (preview) — runs the full pricing engine and returns calculated results, but does not save anything to the database the returned quote id is null use this for pricing previews, what if scenarios, ai driven validation, and integration testing iscommit = true (commit) — runs pricing and persists the quote/order and all line items to the database the returned quote id contains the new record's salesforce id see for details and code examples product identification products can be identified in three ways (in order of precedence) productsku — the product's stockkeepingunit (e g , 'nue platform' ) productname — the product's name (e g , 'nue platform' ) pricebookentryid — a specific pricebookentry id (overrides sku/name resolution) at least one of productsku or productname must be provided when both are given, productsku is used for lookup uom (unit of measure) each product can have multiple pricebookentries at different uoms (e g , user/month at $9 90, user/year at $99) specify the desired uom via uom — uom name string (e g , 'user/month' , 'user/year' ) uomid — uom record id (alternative to name) pricebookentryid — directly specify the price book entry (bypasses uom resolution) https //docs nue io/understanding price calculations the api calculates pricing using this formula chain list price x quantity x subscription term = list total price \ system discount amount = subtotal (= sales price x qty x term) \ discount amount = total price (= net sales price x qty x term) \+ tax amount = total amount where system discount comes from price tags and discount tags (read only, admin configured) discount comes from discretionary discounts (header level or product level) https //docs nue io/understanding subscription term basis and proration is forced to 1 for one time and credit revenue models minimal examples the two examples below show the same quote request in preview and commit modes both execute the identical pricing pipeline — the only difference is whether the result is persisted to the database preview mode ( iscommit = false ) is ideal for validating structure and pricing before creating a real record; commit mode ( iscommit = true ) saves the quote and all quotelineitems as salesforce records see for a deeper comparison preview mode ( iscommit = false ) // 1 find an opportunity with an account opportunity opp = \[select id, accountid from opportunity where accountid != null limit 1]; // 2 build the request ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'my first api quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue platform'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = false; // preview only — no database writes // 3 call the api ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // 4 inspect results system debug('status ' + response status); if (response status == 'succeed') { // quote id is null in preview mode — nothing was saved system assertequals(null, response data quote id); // check for warnings if (response warnings != null) { for (ruby globalapitypes message w response warnings) { system debug('warning ' + w\ errortype + ' — ' + w\ message); } } // pricing is fully calculated even without persisting system debug('line items ' + response data lineitems size()); for (ruby globalapitypes quotelineitemdto li response data lineitems) { quotelineitem qli = li quotelineitem; system debug(qli product2 stockkeepingunit + ' | qty=' + qli quantity + ' | listprice=' + qli ruby listprice c + ' | totalprice=' + qli ruby totalprice c); } } else { // handle errors with structured error codes for (ruby globalapitypes message err response errors) { system debug('error \[' + err errortype + '] ' + err message); } } commit mode ( iscommit = true ) // 1 find an opportunity with an account opportunity opp = \[select id, accountid from opportunity where accountid != null limit 1]; // 2 build the request (same structure as preview) ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'my first api quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue platform'; product uom = 'user/month'; product quantity = 10; request products = new list\<ruby globalapitypes productinput>{ product }; request iscommit = true; // commit — persist quote and quotelineitems to database // 3 call the api ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // 4 inspect results system debug('status ' + response status); if (response status == 'succeed') { // quote id is a real salesforce record id after commit system assertnotequals(null, response data quote id); system debug('created quote ' + response data quote id); // line items are also persisted with salesforce ids for (ruby globalapitypes quotelineitemdto li response data lineitems) { quotelineitem qli = li quotelineitem; system debug(qli product2 stockkeepingunit + ' | qty=' + qli quantity + ' | listprice=' + qli ruby listprice c + ' | totalprice=' + qli ruby totalprice c); } // re query to confirm persistence quote savedquote = \[select id, name, ruby totalprice c from quote where id = \ response data quote id]; system debug('saved quote ' + savedquote name + ' | total ' + savedquote ruby totalprice c); } else { for (ruby globalapitypes message err response errors) { system debug('error \[' + err errortype + '] ' + err message); } } creating a primary quote ( ruby isprimaryquote c = true ) when you set ruby isprimaryquote c = true on the quote header in the createquote request, the committed quote is automatically designated as the primary quote for its opportunity this triggers an asynchronous sync that creates opportunitylineitems matching all non summary quotelineitems — giving the sales team and reporting dashboards an accurate view of the deal's products and pricing directly on the opportunity this is especially valuable when combined with https //docs nue io/automating order generation from primary quote at key opportunity stages when the opportunity reaches a configured stage (e g , "closed won"), nue can automatically generate an order from the primary quote — completing the full quote to cash cycle without manual intervention how it works the createquote call with iscommit = true persists the quote and all quotelineitems because ruby isprimaryquote c = true , the quotelineitem trigger enqueues an opportunityproductsyncqueueable the async job creates one opportunitylineitem per non summary quotelineitem, copying pricing fields (quantity, totalprice, discount, etc ) each opportunitylineitem has a ruby primaryquoteline c back reference to its source quotelineitem the opportunity's ruby primaryquote c lookup is set to the committed quote note "summary" line items ( summaryitem , splititem ) are excluded from sync — these are internal rollup lines created for ramp pricing only lineitem and rampitem types sync to the opportunity note the account and opportunity must exist in a separate transaction before calling createquote with iscommit = true salesforce does not allow callouts (which the pricing engine uses) after uncommitted dml in the same transaction // prerequisites account and opportunity already exist (created in a prior transaction) opportunity opp = \[select id, accountid from opportunity where name = 'enterprise deal q1' limit 1]; // build the request — same as a normal committed quote, plus isprimaryquote ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request quote = new quote( opportunityid = opp id, name = 'enterprise deal — primary quote', ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month', ruby isprimaryquote c = true // ← designate as primary quote ); ruby globalapitypes productinput platform = new ruby globalapitypes productinput(); platform productsku = 'nue platform'; platform uom = 'user/month'; platform quantity = 25; ruby globalapitypes productinput bundle = new ruby globalapitypes productinput(); bundle productsku = 'nue gem edition'; bundle uom = 'user/month'; bundle quantity = 10; request products = new list\<ruby globalapitypes productinput>{ platform, bundle }; request accountid = opp accountid; request iscommit = true; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system debug('status ' + response status); if (response status == 'succeed') { system debug('created primary quote ' + response data quote id); system debug('line items ' + response data lineitems size()); // the quote is now persisted as the primary quote for this opportunity // the async sync will create opportunitylineitems automatically // after the sync completes, you can verify // // list\<opportunitylineitem> olis = \[ // select id, product2 stockkeepingunit, quantity, ruby totalprice c, // ruby primaryquoteline c // from opportunitylineitem // where opportunityid = \ opp id // ]; // system assertequals(response data lineitems size(), olis size()); } what gets synced to each opportunitylineitem true 331,331 left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type see for the full comparison of preview vs commit behavior, including the async oli sync when to use this api true 331,331 left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type articles in this guide true 50,304 61538461538464,307 38461538461536 left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type left unhandled content type
Have a question?
Get answers fast with Nue’s intelligent AI, expert support team, and a growing community of users - all here to help you succeed.
To ask a question or participate in discussions, you'll need to authenticate first.