--- title: "Enable pricing guidance and data in quotes and agreements" slug: "enable-pricing-guidance-and-data-in-quotes-and-agreements" description: "Integrate Price Manager and Price IQ with Zilliant CPQ to seamlessly attach pricing guidance and price data to your quotes to derive insights into your pricing strategy." updated: 2025-02-14T17:30:49Z published: 2025-02-14T17:30:49Z canonical: "docs.zilliant.com/enable-pricing-guidance-and-data-in-quotes-and-agreements" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.zilliant.com/llms.txt > Use this file to discover all available pages before exploring further. # Enable pricing guidance and data in quotes and agreements Zilliant CPQ supports integration with [Zilliant Price IQ](/docs/about-price-iq) and [Zilliant Price Manager](/docs/about-price-manager). This integration enables you to seamlessly attach pricing guidance and price data to your [quotes](/v1/docs/about-quotes) and [agreements](/v1/docs/agreements) to derive insights into your pricing strategy. The following image shows the results of adding pricing data from Price IQ and Price Manager. **Std. Price / Unit** column values come from Price Manager. **Start Discount**, **Target Discount**, and **Floor Discount** columns values come from Price IQ. Based on those values and manually entered **Discount** values, CPQ calculates **Health** values and **Total Price** values for each line. ### ![PIQ and PM integration with CPQ](https://cdn.document360.io/24f960e8-3c1c-4c18-a2c6-83b6ae4aab84/Images/Documentation/PIQ%20and%20PM%20integration%20with%20CPQ.png?sv=2026-02-06&spr=https&st=2026-11-08T07%3A11%3A22Z&se=2026-11-08T08%3A11%3A22Z&sr=c&sp=r&sig=PKtniDR9ibrVxdr8cf6ByHZgwPvlf6VSc6I7mmtB5zU%3D) ## Prerequisites To get started, contact your Zilliant representative. They will perform prerequisite setup tasks to facilitate integration. ## Configure integration The integration operates by using a [Groovy](/docs/about-groovy) script. This script calls specific Zilliant database formulas and returns values to designated fields in a quote or agreement. To attach price guidance and list prices to quotes or agreements, you must: 1. [Create a Groovy script](/docs/enable-pricing-guidance-and-data-in-quotes#create-a-groovy-script). 2. [Upload the Groovy script](/docs/enable-pricing-guidance-and-data-in-quotes#upload-a-groovy-script) to Zilliant CPQ. 3. [Attach the Groovy script](/docs/enable-pricing-guidance-and-data-in-quotes#attach-a-groovy-script-to-a-pricing-scheme) to a pricing step in the active pricing schema. ### Create a Groovy script Create a Groovy script that calls specific Zilliant database formulas and returns the values to designated fields on the quote or agreement. In addition to the [common binding variables](/docs/binding-variables), the `com.imc.iss.groovy.priceiq` [package](https://in-mind-cloud.github.io/content/groovy-doc/2405/com/imc/iss/groovy/priceiq/package-summary.html) ![](https://cdn.document360.io/24f960e8-3c1c-4c18-a2c6-83b6ae4aab84/Images/Documentation/external-link-svgrepo-com.svg?sv=2026-02-06&spr=https&st=2026-11-08T07%3A11%3A22Z&se=2026-11-08T08%3A11%3A22Z&sr=c&sp=r&sig=PKtniDR9ibrVxdr8cf6ByHZgwPvlf6VSc6I7mmtB5zU%3D) and `com.imc.iss.groovy.salesitem` [package](https://in-mind-cloud.github.io/content/groovy-doc/2405/com/imc/iss/groovy/salesitem/package-summary.html) ![](https://cdn.document360.io/24f960e8-3c1c-4c18-a2c6-83b6ae4aab84/Images/Documentation/external-link-svgrepo-com.svg?sv=2026-02-06&spr=https&st=2026-11-08T07%3A11%3A22Z&se=2026-11-08T08%3A11%3A22Z&sr=c&sp=r&sig=PKtniDR9ibrVxdr8cf6ByHZgwPvlf6VSc6I7mmtB5zU%3D) are available for this script. ****Example Groovy script with comments**** ```groovy @Grab(group='org.codehaus.groovy', module='groovy-json', version='2.4.7') // Import necessary classes and libraries import com.imc.context.BaseContext; import com.imc.datamodel.BusinessObject import com.imc.iss.groovy.GroovyCtxUtil import com.imc.iss.groovy.priceiq.GroovyPriceIQHelper import com.imc.iss.price.model.input.document.SalesItem; import com.imc.iss.price.services.pricing.PriceAmount; import com.imc.model.Amount; import com.imc.model.Currency; import com.imc.vocabulary.Schema; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import groovy.json.JsonSlurper; SalesItem salesItemDTOBean = prizableDTOBean; // Retrieve the sales item DTO bean GroovyCtxUtil groovyCtxUtil = groovyCtxUtil;// Retrieve the utility class for ad-hoc data access BaseContext ctx = groovyCtxUtil.getCtx(); // Retrieve the base context from the utility // Retrieve business objects related to the sales item final BusinessObject salesItemBO = salesItemDTOBean.getInstance(); final BusinessObject quoteBO = salesItemDTOBean.getQuoteBO(); final BusinessObject ihpiBO = ctx.commandFactory().getRelAttrValue().businessObject(salesItemBO).businessAttribute(Schema.includesItemHeaderPriceItem).execute().get(); final BusinessObject productBO = ctx.commandFactory().getRelAttrValue().businessObject(salesItemBO).businessAttribute(Schema.isProduct).execute().get(); // If the system uses an opportunity, additional verification is needed here final BusinessObject accountBO = ctx.commandFactory().getRelAttrValue().businessObject(quoteBO).businessAttribute(Schema.quoteContainedBy).execute().get(); // Retrieve ERP IDs, quantity, and other information needed for discount calculation final String productErpId = (String) ctx.commandFactory().getDataAttrValue().businessObject(productBO).businessAttribute(Schema.objectERPId).execute().orElse(""); final String accountErpId = (String) ctx.commandFactory().getDataAttrValue().businessObject(accountBO).businessAttribute(Schema.objectERPId).execute().orElse(""); final BigDecimal qty = (BigDecimal) ctx.commandFactory().getDataAttrValue().businessObject(ihpiBO).businessAttribute(Schema.itemHeaderQuantity).execute().get(); // Retrieve discount guidance from the Zilliant database based on product ERP ID, account ERP ID, and quantity Guidance guidance = getGuidance(productErpId, accountErpId, qty); // Set discount guidance to the line item table if(guidance == null) { // If no guidance is available, set default values ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute18).values(0).allowSetReadOnlyValue().execute(); ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute19).values(0).allowSetReadOnlyValue().execute(); ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute20).values(0).allowSetReadOnlyValue().execute(); ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute21).values("").allowSetReadOnlyValue().execute(); } else { // If guidance is available, set the calculated values    ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute18).values(guidance.startDiscount).allowSetReadOnlyValue().execute(); ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute19).values(guidance.targetDiscount).allowSetReadOnlyValue().execute(); ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute20).values(guidance.floorDiscount).allowSetReadOnlyValue().execute(); // Update health status based on the calculated discount BigDecimal discount = (BigDecimal) ctx.commandFactory().getDataAttrValue().businessObject(ihpiBO).businessAttribute(Schema.itemHeaderDiscount).execute().orElse(BigDecimal.ZERO); if(discount.compareTo(guidance.targetDiscount) <= 0) { ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute21).values("🟢 GOOD").allowSetReadOnlyValue().execute(); } else if(discount.compareTo(guidance.floorDiscount) <= 0) { ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute21).values("🟡 MEDIUM").allowSetReadOnlyValue().execute(); } else { ctx.commandFactory().setDataAttrValues().businessObject(salesItemBO).businessAttribute(Schema.salesItemAttribute21).values("🔴 BAD").allowSetReadOnlyValue().execute(); } } // Return a PriceAmount object with a base amount set to zero return getPriceAmountZERO(); // Functions to retrieve guidance based on product ERP ID, account ERP ID, and quantity Guidance getGuidance(String productErpId, String accountErpId, BigDecimal qty) { if(productErpId.isEmpty() || accountErpId.isEmpty()) return null; def jsonPayload = """ { "formulas": [ "piq_fx_StartDiscount", "piq_fx_TargetDiscount", "piq_fx_FloorDiscount" ], "responseDetails": [ "none" ], "lines": [ { "p_CustomerId": "${accountErpId}", "p_LineLevel": "Product", "p_LevelValue": "${productErpId}", "p_Country": "United States", "p_CurrCode": "USD", "piq_fx_ExpectedDefaultUnits": ${qty.toPlainString()}, "p_Uom": "each" } ] } """ // Make request to the Formula Evaluation service def responseBody = groovyPriceIQHelper.formulaEvaluation(jsonPayload); def jsonResponse = new JsonSlurper().parseText(responseBody); // Retrieve guidance values from the response def startOutput = jsonResponse["piq_fx_StartDiscount"]["outputResults"][0]; def targetOutput = jsonResponse["piq_fx_TargetDiscount"]["outputResults"][0]; def floorOutput = jsonResponse["piq_fx_FloorDiscount"]["outputResults"][0]; if(startOutput == null || targetOutput == null || floorOutput == null) { return null; } def start = startOutput["piq_fx_StartDiscount"][0]; def target = targetOutput["piq_fx_TargetDiscount"][0]; def floor = floorOutput["piq_fx_FloorDiscount"][0]; if(start == "null" && target == "null" && floor == "null") { return null; } return new Guidance(start*100, target*100, floor*100); } // Function to return PriceAmount object with base amount set to zero PriceAmount getPriceAmountZERO() { // Set base amount SalesItem salesItemDTOBean = prizableDTOBean; final Currency salesItemCurrency = salesItemDTOBean.getCurrency(); //sales item currency BigDecimal targetTotalAmountValue = BigDecimal.ZERO; Amount amount = new Amount(); amount.setAmountCurrency(salesItemCurrency); amount.setAmountValue(targetTotalAmountValue); PriceAmount pa = new PriceAmount(); pa.setBaseAmount(amount); pa.setPricingStep(pricingStep); return pa; } // Class to hold guidance values class Guidance { public BigDecimal startDiscount; public BigDecimal targetDiscount; public BigDecimal floorDiscount; public Guidance(BigDecimal startDiscount, BigDecimal targetDiscount, BigDecimal floorDiscount) { this.startDiscount = startDiscount; this.targetDiscount = targetDiscount; this.floorDiscount = floorDiscount; } } ``` As shown in the example image at the top of the page, this Groovy script performs the following tasks: - Imports necessary classes and libraries. - Retrieves information about sales items, quotes, and related business objects. - Retrieves discount guidance from the Zilliant database based on product ERP ID, account ERP ID, and quantity. - Calculates the start, target, and floor discounts for each quote line based on the retrieved discount guidance. - Updates the health status for the quote lines by comparing the manually entered discount with the calculated start, target, and floor discounts. ### Upload a Groovy script [Upload the Groovy script](/docs/upload-a-groovy-script) to Zilliant CPQ. Select **Internal Pricing – Custom Item Calculation** as the script type. ### Attach a Groovy script to a pricing scheme 1. Sign in to Zilliant CPQ with your administrator credentials. 2. Identify or create a [price item type](/docs/internal-pricing-engine#price-item-type) to use for the pricing step that retrieves values from the Zilliant database. Its [price item type category](/docs/price-item-type-category) must be **Groovy Script**. 3. From the left navigation area, select **Pricing**. 4. From the top navigation bar, select **Pricing Schemes**. 5. Select or create an active [pricing scheme](/docs/internal-pricing-engine#pricing-scheme). 6. Select or create a [pricing step](/docs/internal-pricing-engine#create-a-pricing-step) that retrieves values from the Zilliant database. 7. On the pricing step editing dialog, from the **Groovy Script** dropdown list, select your Groovy script.