Developer Resources
Create Quote & Create Order Gl...
Creating Quotes with Standalone Products
17 min
standalone products are individual, non bundled products added directly to a quote this is the most common use case for the https //docs nue io/create quotes and orders each product is specified as a ruby globalapitypes productinput in the products list of the request product identification products can be identified in three ways, in order of preference method field example sku (preferred) productsku 'nue platform' product name productname 'nue platform' pricebookentry id pricebookentryid a salesforce pricebookentry record id when using productsku or productname , the api resolves the correct pricebookentry based on the product's https //docs nue io/unit of measures uoms , currency (in https //docs nue io/multiple currencies orgs), and any https //docs nue io/manage custom attributes in price book entries if both productsku and productname are provided, productsku takes precedence if neither is provided, validation returns product sku or name required revenue models each product has a revenue model that determines how pricing is calculated revenue model term behavior pricing formula recurring uses the quote's subscription term (e g , 12 months) listprice x quantity x term = listtotalprice onetime term is forced to 1, regardless of quote term listprice x quantity x 1 = listtotalprice usage consumption based varies by usage configuration credit prepaid credit balance varies by credit configuration crbd committed revenue based deal revenue committed pricing ccrbd committed contracted revenue based deal committed contracted pricing use cases 1\ single product the simplest case add one recurring product to a quote // existing opportunity with an account opportunity opp = \[select id, accountid from opportunity where id = \ oppid]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request iscommit = false; request accountid = opp accountid; request quote = new quote( name = 'single product quote', opportunityid = opp id, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); ruby globalapitypes productinput prod = new ruby globalapitypes productinput(); prod productsku = 'nue platform'; prod uom = 'user/month'; prod quantity = 10; request products = new list\<ruby globalapitypes productinput>{ prod }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // expected 1 line item // pricing listprice($100) x qty(10) x term(12) = listtotalprice($12,000) system assertequals('succeed', response status); system assertequals(1, response data lineitems size()); 2\ multiple products in same request add two or more products in a single api call each product becomes a separate line item opportunity opp = \[select id, accountid from opportunity where id = \ oppid]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request iscommit = false; request accountid = opp accountid; request quote = new quote( name = 'multi product quote', opportunityid = opp id, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // product 1 nue on salesforce ruby globalapitypes productinput prod1 = new ruby globalapitypes productinput(); prod1 productsku = 'nue on salesforce'; prod1 uom = 'user/month'; prod1 quantity = 50; // product 2 nue platform ruby globalapitypes productinput prod2 = new ruby globalapitypes productinput(); prod2 productsku = 'nue platform'; prod2 uom = 'user/month'; prod2 quantity = 10; request products = new list\<ruby globalapitypes productinput>{ prod1, prod2 }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // expected 2 line items, each priced independently system assertequals('succeed', response status); system assertequals(2, response data lineitems size()); 3\ product by name use productname instead of productsku when the sku is not known the api looks up the product by its name field and resolves the sku internally ruby globalapitypes productinput prod = new ruby globalapitypes productinput(); prod productname = 'nue platform'; // uses name instead of sku prod uom = 'user/month'; prod quantity = 10; request products = new list\<ruby globalapitypes productinput>{ prod }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // behaves identically to using productsku = 'nue platform' system assertequals('succeed', response status); note if both productsku and productname are provided, productsku takes precedence the productname lookup queries by product2 name , so the value must match exactly 4\ product by sku (default) sku based identification is the default and preferred method skus are stable identifiers that do not change across environments ruby globalapitypes productinput prod = new ruby globalapitypes productinput(); prod productsku = 'nue platform'; // product2 stockkeepingunit prod uom = 'user/month'; prod quantity = 10; 5\ mixed revenue models (recurring + one time) a single quote can contain products with different revenue models recurring products use the quote's subscription term for pricing; one time products always use a term of 1 opportunity opp = \[select id, accountid from opportunity where id = \ oppid]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request iscommit = false; request accountid = opp accountid; request quote = new quote( name = 'mixed revenue model quote', opportunityid = opp id, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // recurring product term = 12 months ruby globalapitypes productinput recurring = new ruby globalapitypes productinput(); recurring productsku = 'nue platform'; recurring uom = 'user/month'; recurring quantity = 10; // one time product term forced to 1 regardless of quote term ruby globalapitypes productinput onetime = new ruby globalapitypes productinput(); onetime productsku = 'implementation service'; onetime uom = 'hour'; onetime quantity = 20; request products = new list\<ruby globalapitypes productinput>{ recurring, onetime }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // expected 2 line items // line 1 (recurring) $100 x 10 x 12 = $12,000 // line 2 (onetime) $150 x 20 x 1 = $3,000 system assertequals('succeed', response status); system assertequals(2, response data lineitems size()); 6\ one time products only quotes can consist entirely of one time products each product uses its own uom, but all have their term forced to 1 opportunity opp = \[select id, accountid from opportunity where id = \ oppid]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request iscommit = false; request accountid = opp accountid; request quote = new quote( name = 'one time products quote', opportunityid = opp id, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // implementation service — billed per hour ruby globalapitypes productinput svc = new ruby globalapitypes productinput(); svc productsku = 'implementation service'; svc uom = 'hour'; svc quantity = 40; // unlimited online training — billed per account ruby globalapitypes productinput training = new ruby globalapitypes productinput(); training productsku = 'unlimited online training'; training uom = 'account'; training quantity = 1; // usb security key — billed each ruby globalapitypes productinput hardware = new ruby globalapitypes productinput(); hardware productsku = 'usb security key'; hardware uom = 'each'; hardware quantity = 50; request products = new list\<ruby globalapitypes productinput>{ svc, training, hardware }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // expected 3 line items, all with term = 1 // even though the quote header has term = 12, one time products ignore it system assertequals('succeed', response status); system assertequals(3, response data lineitems size()); 7\ duplicate products (same sku twice) adding the same product sku multiple times creates separate, independent line items this is useful when the same product needs different configurations (e g , different quantities, discounts, or price tags on each line) opportunity opp = \[select id, accountid from opportunity where id = \ oppid]; ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); request iscommit = false; request accountid = opp accountid; request quote = new quote( name = 'duplicate products quote', opportunityid = opp id, ruby subscriptionstartdate c = date today(), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // first instance 10 licenses ruby globalapitypes productinput prod1 = new ruby globalapitypes productinput(); prod1 productsku = 'nue platform'; prod1 uom = 'user/month'; prod1 quantity = 10; // second instance 5 licenses (same sku, different quantity) ruby globalapitypes productinput prod2 = new ruby globalapitypes productinput(); prod2 productsku = 'nue platform'; prod2 uom = 'user/month'; prod2 quantity = 5; request products = new list\<ruby globalapitypes productinput>{ prod1, prod2 }; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // expected 2 separate line items for the same product // line 1 $100 x 10 x 12 = $12,000 // line 2 $100 x 5 x 12 = $6,000 system assertequals('succeed', response status); system assertequals(2, response data lineitems size()); key behaviors uom must match a price book entry the uom value on a productinput must match an existing https //docs nue io/price books for that product in the quote's price book if no matching price book entry is found, the api returns a business logic error // this will fail if no pricebookentry exists for nue platform with uom "license/year" ruby globalapitypes productinput prod = new ruby globalapitypes productinput(); prod productsku = 'nue platform'; prod uom = 'license/year'; // wrong uom — no matching price book entry prod quantity = 10; pricing formula for each line item, the pricing engine calculates listtotalprice = listprice x quantity x term where listprice comes from the matched price book entry ( pricebookentry unitprice ) quantity comes from productinput quantity term comes from the quote's ruby subscriptionterm c https //docs nue io/understanding subscription term basis and proration (for recurring products) or 1 (for one time products) start date and end date inheritance if a product does not specify its own startdate and enddate , these values are inherited from the quote header's ruby subscriptionstartdate c and ruby subscriptionenddate c similarly, subscriptionterm and subscriptiontermdimension fall back to the quote level values if not set on the product response structure each line item in the response is a ruby globalapitypes quotelineitemdto containing field description quotelineitem the quotelineitem sobject with all calculated pricing fields id a temporary reference id (replaced with real id on commit) parentid null for standalone products (used for bundle children) uom the resolved uom object with name, quantity dimension, and term dimension product product metadata including revenue model and configuration appliedpricetags list of https //docs nue io/price and discount tags evaluated for this line (empty for standalone with no tags)
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.