Skip to main content

QCharge Class


QCharge Class

This article describes the global methods in the QCharge class. The QCharge class: 

  • Is designed to minimally represent the QuoteRatePlanCharge objects.
  • Is Used by the services in CPQ X to replace the legacy API zCharge.
  • Is used to interface with QuoteRatePlanCharge objects. 
  • Contains utility methods for setting tier level fields.
  • Handles automatic recalculation upon field value changes.

QCharge Global Methods

The QCharge class includes the following global methods.

Method Type Description
get(String fieldName) Object

Retrieves a field value from the QuoteRatePlanCharge record.

getParentPlan QPlan

Retrieves the parent QPlan of this QCharge instance.

getRecord QuoteRatePlanCharge__c Retrieves the QuoteRatePlanCharge instance that the QCharge object represents.
getTiers List<QTier> Gets a deeply cloned List of QTier records that belong to this QCharge. Returns an empty List if the charge model does not support tiers.
isChanged Boolean

Returns true if the state of this record is different from what is last retrieved from DB.

areTiersUpdated Boolean

Returns true if any QTiers on the QCharge have been updated.

isSaved Boolean

Returns true if this record has been inserted into the DB.

isTieredCharge Boolean

Returns true if the QuoteRatePlanCharge object uses a Charge Model that holds tiers.

put(String fieldName, Object value) Object

Sets a field value on the QuoteRatePlanCharge record. Returns the previous field value.

put(String fieldName, Object value, Boolean ignoreFieldLevelAccess) Object Sets a field value on the QuoteRatePlanCharge record. Returns the previous field value.
If ignoreFieldLevelAccess is flagged, this call will not raise security exceptions even if the user does not have Edit access to the given field.
setTiers(List<QTier> qTiers) void Sets the QTier List under this QCharge record. It first runs a validation check to ensure the data integrity.

Recalculation Table

The put() operation on certain fields of the QuoteRatePlanCharge record will trigger recalculation processes. The table below lists these fields and the corresponding recalculation logic upon value changes

When any of these fields are not valid for a particular Charge Model or Charge Type, slight modifications to these formulas will be made to accommodate.

Field Changed Action(s) Taken Recalculation Logic
Discount__c Recalculation is applied

1st) Effective Price = List Price - (List Price * (Discount / 100))

2nd) Total = Effective Price * Quantity

3rd) List Total = List Price * Quantity

EffectivePrice__c Recalculation is applied

1st) Effective Price = List Price - (List Price * (Discount / 100))

2nd) Total = Effective Price * Quantity.

ListPrice__c Recalculation is applied

1st) Discount = -(Effective Price - List Price)*(100 / List Price)

2nd) Total = Effective Price * Quantity

Quantity__c Recalculation is applied

1st) Total = Effective Price * Quantity

2nd) List Total = List Price * Quantity

Total__c Recalculation is applied

1st) Effective Price = Total / Quantity

2nd) Discount = -(Effective Price - List Price)*(100 / List Price)

Security Considerations

  • When using the QCharge global method to assign new charge values, the user’s Edit and Field-Level Access is checked to validate that the change can be made. For example, for a custom integration that uses the QCharge global method to update the Quantity of a charge, the user must have the Edit access to QuoteRatePlanCharge and the Field-Level Edit access to Quantity; otherwise, a field-level violation exception would occur. 
  • Additionally, when saving these changed plans and charges through QPlanWriter, additional validation is run to ensure the user has the Edit access to the Quote and the Field-Level Edit access to any changed fields; otherwise, invalid access exceptions will occur.
    • As of Quotes 9.33, it is possible to pass an additional parameter ignoreFieldLevelAccess to the QCharge.put() global method to bypass updatability checks. Invoking this method without including this parameter will continue to validate access as before. It means that any custom integration that invokes processes to update charge information should either respect field-level access, or override field-level access and ensure proper validation of access rights when exposing actions to users that systematically change charge values.

Sample Code

Get and Set Fields from a QuoteRatePlanCharge Object

The following sample code shows how to set and retrieve field values on the QuoteRatePlanCharge record through the QCharge.

public void test(zqu.QCharge charge) {
    // Get Initial Value
    System.assertEquals('My Value', (String) charge.get('MyChargeField__c'));
    System.assertEquals(false, charge.isChanged());
    // Get Updated Value
    charge.put('MyChargeField__c', 'My New Value');
    System.assertEquals('My New Value', (String) charge.get('MyChargeField__c'));
    System.assertEquals(true, charge.isChanged());

Update a Field that Results in a Recalculation

The following sample code shows how the recalculation is triggered when updating the Discount__c field value.

public void test(zqu.QCharge charge) {
    // Assert Initial values
    System.assertEquals(10, (Double) charge.get('zqu__ListPrice__c'));
    System.assertEquals(0, (Double) charge.get('zqu__Discount__c'));
    System.assertEquals(10, (Double) charge.get('zqu__EffectivePrice__c'));
    System.assertEquals(false, charge.isChanged());
    // Update value and test recalculation
    charge.put('zqu__Discount__c', 50);
    System.assertEquals(10, (Double) charge.get('zqu__ListPrice__c'));
    System.assertEquals(50, (Double) charge.get('zqu__Discount__c'));
    System.assertEquals(true, charge.isChanged());
    System.assertEquals(5, (Double) charge.get('zqu__Effective_Price__c'));

Update a Field on the First Tier under the QCharge

public void test(zqu.QCharge charge) {
    if (charge.isTieredCharge()) {
        // Assert Initial values
        System.assertEquals(false, charge.areTiersUpdated());
        System.assertEquals(false, charge.isChanged());
        // Update a value on the first tier
        List<zqu.QTier> tiers = charge.getTiers();
        tiers.get(0).put('MyTierField__c', 'My New Value');
        System.assertEquals('My New Value', 
                            (String) tiers.get(0).get('MyTierField__c'));
        System.assertEquals(true, tiers.get(0).isChanged());
        // Charge has not been updated until the tiers have been set on the Charge
        System.assertEquals(false, charge.areTiersUpdated());
        System.assertEquals(false, charge.isChanged());
        // Set updated tiers on the Charge and verify
        System.assertEquals(true, charge.areTiersUpdated());
        System.assertEquals(true, charge.isChanged());