Developer Resources
Create Quote & Create Order Gl...
Multi-Currency Quotes
15 min
in https //docs nue io/multiple currencies salesforce orgs, the ruby globalquoteserviceapi createquote() https //docs nue io/apex global methods and services method automatically selects https //docs nue io/price books matching the quote's currency currency is set via currencyisocode on the quote sobject prerequisites before creating quotes in non default currencies, ensure multi currency is enabled in your salesforce org (setup > company information > currency management) price book entries exist for the target currency and product/ https //docs nue io/unit of measures uoms combination the opportunity supports the target currency (opportunity currency must match or the account must support multiple currencies) https //docs nue io/product bundle productoption records link to price book entries in the target currency (for bundle products) setting the currency currencyisocode is a dynamic field that only exists in multi currency orgs set it using put() on the quote sobject quote q = new quote( opportunityid = europpid, name = 'eur quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); q put('currencyisocode', 'eur'); if currencyisocode is not set, it defaults to the running user's default currency (via userinfo getdefaultcurrency() ) use cases 1\ eur standalone product when currencyisocode is set to 'eur' , the pricing engine selects the eur price book entry instead of the usd one ruby globalapitypes createquoterequest request = new ruby globalapitypes createquoterequest(); quote q = new quote( opportunityid = europpid, name = 'eur standalone quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); q put('currencyisocode', 'eur'); request quote = q; 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; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); // eur price book entry selected (e g , eur 89 00 instead of usd 99 00) quotelineitem qli = response data lineitems\[0] quotelineitem; system debug('list price (eur) ' + qli ruby listprice c); 2\ usd baseline comparison the same product without eur currency set selects the usd price book entry at the usd list price quote q = new quote( opportunityid = usdoppid, name = 'usd baseline quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); // currencyisocode defaults to user's default (usd) request quote = q; // same product, same uom — but resolves to usd price book entry (e g , $99 00) 3\ no pricebookentry for currency when a product does not have a price book entry in the requested currency, the api returns a failure response with an error identifying the missing currency/uom combination quote q = new quote( opportunityid = jpyoppid, name = 'jpy quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); q put('currencyisocode', 'jpy'); request quote = q; 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; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('failure', response status); // error message includes filter details currency, uom, product for (ruby globalapitypes message err response errors) { system debug('error ' + err message); // e g , "no pricebook entry found for product nue platform with uom user/month and currency jpy" } 4\ eur bundles bundle creation in eur requires that productoption records link to price book entries in the eur currency if the productoptions reference usd only price book entries, the system returns a pricebook entry mismatch error this is correct behavior that matches the nue ui quote q = new quote( opportunityid = europpid, name = 'eur bundle quote', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month' ); q put('currencyisocode', 'eur'); request quote = q; ruby globalapitypes productinput bundle = new ruby globalapitypes productinput(); bundle productsku = 'nue gem edition'; bundle uom = 'user/month'; bundle quantity = 5; ruby globalapitypes productinput addon = new ruby globalapitypes productinput(); addon productsku = 'usb security key'; bundle addons = new list\<ruby globalapitypes productinput>{ addon }; request products = new list\<ruby globalapitypes productinput>{ bundle }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); // success only if all productoption price book entries exist in eur // failure with pricebook entry mismatch if any child price book entry is usd only 5\ eur line level discount discretionary discounts work identically in non usd currencies the discount percentage is applied to the eur list price ruby globalapitypes productinput product = new ruby globalapitypes productinput(); product productsku = 'nue platform'; product uom = 'user/month'; product quantity = 10; product discount = 15 0; // 15% discount on eur price request products = new list\<ruby globalapitypes productinput>{ product }; 6\ eur header discount header level discounts ( quote ruby discount c ) propagate to eur priced lines in the same way as usd lines quote q = new quote( opportunityid = europpid, name = 'eur header discount', ruby subscriptionstartdate c = date today(), ruby subscriptionenddate c = date today() addmonths(12), ruby subscriptionterm c = 12, ruby subscriptiontermdimension c = 'month', ruby discount c = 10 0 // 10% header discount ); q put('currencyisocode', 'eur'); request quote = q; 7\ eur committed quote the full commit flow works in eur with database persistence the saved quote and quotelineitems reflect eur pricing request iscommit = true; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('succeed', response status); system assertnotequals(null, response data quote id); // re query to confirm eur persistence quote savedquote = \[select id, currencyisocode from quote where id = \ response data quote id]; system assertequals('eur', (string)savedquote get('currencyisocode')); 8\ partial pricebookentry coverage when some products in a request have price book entries in the target currency and others do not, the entire request fails the error message identifies exactly which product/uom/currency combination is missing // product a has eur price book entry, product b does not ruby globalapitypes productinput proda = new ruby globalapitypes productinput(); proda productsku = 'nue platform'; // has eur price book entry proda uom = 'user/month'; proda quantity = 10; ruby globalapitypes productinput prodb = new ruby globalapitypes productinput(); prodb productsku = 'addon only usd'; // no eur price book entry prodb uom = 'license/year'; prodb quantity = 1; request products = new list\<ruby globalapitypes productinput>{ proda, prodb }; request iscommit = false; ruby globalapitypes createquoteresponse response = ruby globalquoteserviceapi createquote(request); system assertequals('failure', response status); // error identifies the specific product that failed for (ruby globalapitypes message err response errors) { system debug(err errortype + ' ' + err message); // e g , "business logic error no pricebook entry found for product addon only usd // with uom license/year and currency eur" } key behaviors behavior details set currency via put() currencyisocode is a dynamic field use quote put('currencyisocode', 'eur') it is not available as a constructor argument in all orgs price book entry matching filters pricebookentry selection filters by product + uom + currency + pricingattributes bundle children must match all productoption price book entries within a bundle must be available in the target currency a mismatch on any child returns pricebook entry mismatch discounts work identically discount percentages, discount amounts, and https //docs nue io/price and discount tags all work the same across currencies default currency if currencyisocode is not set, it defaults to the running user's default currency ( userinfo getdefaultcurrency() ) entire request fails on mismatch if any product in the request lacks a price book entry in the target currency, the entire request fails (no partial success) opportunity currency alignment the opportunity associated with the quote should support the same currency troubleshooting symptom likely cause resolution business logic error no pricebook entry found no price book entry exists for the product/uom/currency combination create a pricebookentry for the product in the target currency pricebook entry mismatch bundle child productoption links to a price book entry in a different currency update the productoption to reference a price book entry in the correct currency wrong price returned price book entry exists in both currencies; wrong one selected verify currencyisocode is set correctly on the quote currencyisocode field not recognized org does not have multi currency enabled enable multi currency in setup > company information
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.