Calculating True End Date and Subscription Term

The sample JavaScript script can be used in the Quote Line Calculator to calculate values and store maximum values for the custom quote line fields True Effective End Date and True Effective Term.

Required Editions
Available in: Salesforce CPQ Winter ’16 and later

Salesforce CPQ no longer provides support for Legacy Quote Calculator plugins. Check out the Javascript Quote Calculator Plugin for support and improved features.

Note

The sample script assumes the Salesforce admin created custom fields True Effective End Date and True Effective Term on the Quote Line object.

Note

Example 

1global class QCPWinter16Legacy2 implements SBQQ.QuoteCalculatorPlugin, SBQQ.QuoteCalculatorPlugin2 {
2
3/* This QCP examples calculates and stores the effective end date on each quote line, as well as the effective term.
4   It also stores the max(effective end date) and max(effective term) on the Quote object
5*/
6
7
8    /* NOTE: the getReferencedFields method is no longer required if you use the ReferencedFields field set on
9 the Quote Line object. 
10             This field set must be created as it's not a managed one.
11       NOTE: if you need to access Quote fields, you can create the ReferencedFields field set on the Quote object as well.
12       NOTE: if you do not use the getReferencedFields method, you can remove SBQQ.QuoteCalculatorPlugin2 from the class declaration.
13    */
14    global Set<String> getReferencedFields() {
15        return new Set<String>{
16            /* Note: add fields using the following format - Only add fields referenced
17                               
18               by the plugin and not in the Line Editor field set on the Quote Line object
19            String.valueOf(SBQQ__QuoteLine__c.My_Field_API_Name__c)
20            */
21            String.valueOf(SBQQ__QuoteLine__c.True_Effective_End_Date__c),
22            String.valueOf(SBQQ__QuoteLine__c.True_Effective_Term__c),
23            
24            String.valueOf(SBQQ__Quote__c.True_Effective_End_Date__c),
25            String.valueOf(SBQQ__Quote__c.True_Effective_Term__c),
26            
27            String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveStartDate__c),
28            String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveEndDate__c),
29            String.valueOf(SBQQ__QuoteLine__c.SBQQ__SubscriptionTerm__c),
30            String.valueOf(SBQQ__QuoteLine__c.SBQQ__DefaultSubscriptionTerm__c),
31            
32            String.valueOf(SBQQ__Quote__c.SBQQ__SubscriptionTerm__c)
33        };
34    }
35
36    global void onBeforePriceRules(SObject quote, SObject[] lines) {
37    }
38    
39    global void onAfterPriceRules(SObject quote, SObject[] lines) {
40    }
41    
42    global void onBeforeCalculate(SObject quote, SObject[] lines) {
43    }
44    
45    global void onAfterCalculate(SObject quote, SObject[] lines) {
46        Date maxEffectiveEndDate = null;
47        Decimal maxEffectiveTerm = 0;
48        for(SObject line : lines) {
49            Date trueEndDate = calculateEndDate(quote, line);
50            Decimal trueTerm = getEffectiveSubscriptionTerm(quote, line);
51            if(maxEffectiveEndDate == null || maxEffectiveEndDate < trueEndDate) {
52                maxEffectiveEndDate = trueEndDate;
53            }
54            if(maxEffectiveTerm < trueTerm) {
55                maxEffectiveTerm = trueTerm;
56            }
57            line.put(SBQQ__QuoteLine__c.True_Effective_End_Date__c, trueEndDate);
58            line.put(SBQQ__QuoteLine__c.True_Effective_Term__c, trueTerm);
59        }
60        quote.put(SBQQ__Quote__c.True_Effective_End_Date__c, maxEffectiveEndDate);
61        quote.put(SBQQ__Quote__c.True_Effective_Term__c, maxEffectiveTerm);
62    }
63    
64    global void onInit(SObject[] lines) {
65    }
66    
67    private Date calculateEndDate(SObject quote, SObject line) {
68        Date startDate = (Date)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveStartDate__c));
69        Date endDate = (Date)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveEndDate__c));
70        if ((startDate != null) && (endDate == null)) {
71            /* Note: we are assuming that Subscription Term Unit is Month in the package settings */
72            endDate = startDate.addMonths(getEffectiveSubscriptionTerm(quote, line).intValue()).addDays(-1);
73            /* Note: we are assuming that Subscription Term Unit is Day in the package settings */
74//          endDate = startDate.addDays(getEffectiveSubscriptionTerm(line).intValue() - 1);
75        }
76        return endDate;
77    }
78    
79    private Decimal getEffectiveSubscriptionTerm(SObject quote, SObject line) {
80        Decimal lineTerm = null;
81        Date startDate = (Date)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveStartDate__c));
82        Date endDate = (Date)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__EffectiveEndDate__c));
83        if ((startDate != null) && (endDate != null)) {
84            /* Note: we are assuming that Subscription Term Unit is Month in the package settings */
85            lineTerm = startDate.monthsBetween(endDate.addDays(1));
86            /* Note: we are assuming that Subscription Term Unit is Day in the package settings */
87//            lineTerm = startDate.daysBetween(endDate.addDays(1));
88        } else {
89            lineTerm = (Decimal)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__SubscriptionTerm__c));
90            if (lineTerm == null) {
91                lineterm = (Decimal)quote.get(String.valueOf(SBQQ__Quote__c.SBQQ__SubscriptionTerm__c));
92                if (lineTerm == null) {
93                    return (Decimal)line.get(String.valueOf(SBQQ__QuoteLine__c.SBQQ__DefaultSubscriptionTerm__c));
94                }
95            }
96        }
97        return lineTerm;
98    }
99    
100}