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.
- As of Quotes 9.33, it is possible to pass an additional parameter
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 charge.setTiers(tiers); System.assertEquals(true, charge.areTiersUpdated()); System.assertEquals(true, charge.isChanged()); }