Product Selector JavaScript Plugin
In Zuora Quotes, you can implement a custom JavaScript plugin to programmatically set values of the standard and custom fields on the charge rows in the Lightning Guided Product Selector. When you write a custom JavaScript file that implements predefined functions and upload that file into Salesforce, Zuora Quotes executes the custom code when your user updates a value on a charge line item in the Product Selector.
The JavaScript plugin is only available in the new Lightning Guided Product Selector of the version 7.0 and later. The Titanium Product Selector does not support the JavaScript plugin.
Update Charge
Signature
zquGlobalPlugin.updateZCharge(zCharge)
Description
The zquGlobalPlugin.updateZCharge
method triggers an update of the field values on the input parameter charge as below:
- Non-pricing fields on the input Quote Rate Plan Charge. You can update multiple non-pricing fields with the plugin. Updating these fields do not trigger a recalculation of the price.
- One pricing field at a time
The plugin can set one of the following field values on the Quote Rate Plan Charge object. Setting these fields will trigger a recalculation.
- Quantity
- Discount
- Effective Price
- Total
The zquGlobalPlugin.updateZCharge
method will return an error if more than one pricing field was updated between the current charge and previous version of the charge.
Number of pricing fields updated |
Behavior |
---|---|
2 | Throws an error "Multiple pricing fields updated on zCharge {zCharge.Id}: {zCharge.Name}" |
1 | Updates the pricing field in addition to custom field and non-pricing fields |
0 | Updates custom fields and non-pricing fields |
- If the Orders feature is enabled in your org, the updates by the plugin trigger a cascade recalculation against future segments of the charge.
This feature is only available if you have the Orders feature enabled.
Post Recalculation
Signature
ProductSelectorPlugin.postRecalculateZCharge(
previousCharge,
currentCharge,
zChargeGroup,
quote,
allChargeGroups)
Description
In your JavaScript plugin, define ProductSelectorPlugin.postRecalculateZCharge
and make the call to the zquGlobalPlugin.updateZCharge
method inside the function.
Inject Custom JavaScript
To inject a custom JavaScript:
- Implement your custom JavaScript.
- Browse to Setup > Develop > Static Resources.
- Click New.
- Specify the following field values:
- Name: Specify ProductSelectorPlugin. Only the JavaScript with the exact name is recognized in the Product Selector.
- In the File field, Upload the JavaScript file you created in the Step #1.
- Cache Control: Set to Public.
Sample Code
The below is a sample code for Product Selector Plugin.
// Define the plugin method as a global object var ProductSelectorPlugin = function(){ return { postRecalculateZCharge : function(previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { // If the user sets the discount to 30, reset the discount to be 90 if(currentZCharge['DISCOUNT'] == 30.00) { currentZCharge['DISCOUNT'] = '90'; zquGlobalPlugin.updateZCharge(currentZCharge); } // If the quantity exceeds 1000, reset the value to exactly 1000 else if(currentZCharge['QUANTITY'] > 1000) { currentZCharge['QUANTITY'] = 1000; zquGlobalPlugin.updateZCharge(currentZCharge); } } }; }();
The below is a sample code using custom fields in Product Selector Plugin.
var ProductSelectorPlugin = function(){ return { postRecalculateZCharge : function(previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { // Plain charges receive 0% discount, Gold receive 10% discount, // Platinum receive 20% discount if(currentZCharge.chargeObject['family__c'] == 'Plain') { currentZCharge['DISCOUNT'] = '0'; zquGlobalPlugin.updateZCharge(currentZCharge); } else if(currentZCharge.chargeObject['family__c'] == 'Gold') { currentZCharge['DISCOUNT'] = '10'; zquGlobalPlugin.updateZCharge(currentZCharge); } else if(currentZCharge.chargeObject['family__c'] == 'Platinum') { currentZCharge['DISCOUNT'] = '20'; zquGlobalPlugin.updateZCharge(currentZCharge); } } }; }();
The sample code below implements the Product Selector Plugin that changes prices based on billing frequency.
var ProductSelectorPlugin = function(){ return { postRecalculateZCharge : function(previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { // Only proceed if the Effective Price is editable if(!currentZCharge.isEffectivePriceEditable) return; var updatedBillingFrequency = currentZCharge.chargeObject['billingfrequency__c']; var previousBillingFrequency = previousZCharge.chargeObject['billingfrequency__c']; // If there is no change in billing frequency, // do not recalculate pricing fields if(updatedBillingFrequency == previousBillingFrequency) return; var priceMultiplier = 1; if(updatedBillingFrequency == 'Monthly') { if(previousBillingFrequency == 'Bi-Annually') priceMultiplier = 6; else if(previousBillingFrequency == 'Annually') priceMultiplier = 12; } else if(updatedBillingFrequency == 'Bi-Annually') { if(previousBillingFrequency == 'Monthly') priceMultiplier = 1/6; else if(previousBillingFrequency == 'Annually') priceMultiplier = 2; } else if(updatedBillingFrequency == 'Annually') { if(previousBillingFrequency == 'Monthly') priceMultiplier = 1/12; else if(previousBillingFrequency == 'Bi-Annually') priceMultiplier = 1/2; } // Calculate the new price and perform recalculation var updatedPrice = parseFloat(currentZCharge.EFFECTIVE_PRICE) * priceMultiplier; currentZCharge['EFFECTIVE_PRICE'] = updatedPrice.toString(); zquGlobalPlugin.updateZCharge(currentZCharge); } }; }();
The sample code below implements the Product Selector Plugin that updates all the charges in the charge groups being passed in.
var ProductSelectorPlugin = function () { return { postRecalculateZCharge: function (previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { var currentQuantity = currentZCharge['QUANTITY']; var currentModel = currentZCharge['MODEL']; var currentDiscount = currentZCharge['DISCOUNT']; try { // if the current discount is set to 100, alert the user and revert if (parseFloat(currentDiscount) === 100.0) { alert('Cannot set discount to 100%'); currentZCharge['DISCOUNT'] = previousZCharge['DISCOUNT']; zquGlobalPlugin.updateZCharge(currentZCharge); return; } // for all zCharges of the same model, update to the same Quantity and Discount allChargeGroups.forEach(function (group) { group.zCharges.forEach(function (charge) { if (charge['MODEL'] === currentModel) { if(charge['QUANTITY'] !== '-' && charge['isQuantityEditable']) { charge['QUANTITY'] = currentQuantity; } if(charge['isDiscountEditable']) { charge['DISCOUNT'] = currentDiscount; } zquGlobalPlugin.updateZCharge(charge); } }); }); } catch (e) { alert('Error occurred: ' + e.message); } } }; }();
Fields impacted by Display Scale Settings
Use the below sample code to obtain the fields that are impacted by display scale settings:
var ProductSelectorPlugin = function(){ return { postRecalculateZCharge : function(previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { allChargeGroups.forEach(function (group) { group.zCharges.forEach(function (charge) { if(charge['Id'] === currentZCharge['Id']){ console.log('currentZCharge-->' , JSON.stringify(currentZCharge)); //All fields that are impacted by Display Scale Settings will be displayed. } }); }); } }; }();
Fields not impacted by Display Scale Settings
Use the below sample code to obtain the fields that are not impacted by display scale settings:
var ProductSelectorPlugin = function(){ return { postRecalculateZCharge : function(previousZCharge, currentZCharge, chargeGroup, quote, allChargeGroups) { allChargeGroups.forEach(function (group) { group.zCharges.forEach(function (charge) { if(charge['Id'] === currentZCharge['Id']){ console.log('charge.zqc-->', JSON.Stringify(charge.zqc)); //Inspect the log; fields prefixed with 'd_' like d_EffectivePrice will remain unaffected. } }); }); } }; }();
To retrieve a particular field while disregarding display scale settings, you can use the subsequent code snippet:
For instance, to acquire the effective price without adhering to display scale settings.
console.log(‘effective price-->’, charge.zqc.d_EffectivePrice));
Troubleshoot your implementation
If you encounter issues when using the Product Selector JavaScript plugin, try the following steps to facilitate troubleshooting:
- Check and ensure that you upload files in the .JS format. If you upload a file in the .JS format, the MIME type is
text/javascript
. If you upload a text file, the MIME type istext/plain
, which can result in plugin errors. - If you find that the plugin is not working, copy one of the preceding sample codes to a file, then upload the file and test if it is working.
- To see all possible errors, enter the console of your browser and add logs to verify whether the passed-in values are correct. For example, enter
console.log(currentZCharge.DISCOUNT + " charge discount")
.