Hi I am trying to delete the following APEX class in production and I'm getting the following error.

Steps taken:

  1. loaded apex class
  2. updated status of Meta datga xml file from "Active" to "Deleted"

Error message:

Run Failures: CustomQuoteAfter. line 2, column 35: trigger body is invalid and failed recompilation: Invalid type: CustomQuoteService

Deployment Log:

Deploy Results:

File Name:    classes/CustomQuoteService.cls
Full Name:  CustomQuoteService
Action:  NO ACTION
Result:  SUCCESS
Problem: n/a

File Name:    package.xml
Full Name:  package.xml
Action:  UPDATED
Result:  SUCCESS
Problem: n/a

# Test Results: Run Failures: CustomQuoteAfter. line 2, column 35: trigger body is invalid and failed recompilation: Invalid type: CustomQuoteService


public with sharing class CustomQuoteService {
  public void processTriggerAfter(SBQQ__Quote__c[] quotes, Map<Id,SBQQ__Quote__c> oldMap) {
    Map<Id,SBQQ__Quote__c> quotesById = new Map<Id,SBQQ__Quote__c>(quotes);
    SBQQ__Quote__c[] changedServiceLevel = new SBQQ__Quote__c[0];
    for (SBQQ__Quote__c quote : quotes) {
      SBQQ__Quote__c old = oldMap.get(quote.Id);
      if (quote.Service_Level__c != old.Service_Level__c) {

    if (!changedServiceLevel.isEmpty()) {
      Map<String,Product2> productsByKey = new Map<String,Product2>();
      for (Product2 product : 
        [SELECT SBQQ__SubscriptionCategory__c, SBQQ__SubscriptionTerm__c,
           Service_Level__c, Term_Type__c, SBQQ__SubscriptionPercent__c, SBQQ__SubscriptionPricing__c
         FROM Product2 WHERE SBQQ__SubscriptionPricing__c != null AND IsActive = true]) {
        productsByKey.put(generateKey(product), product);

      Map<String,SBQQ__QuoteLine__c> linesByKey = new Map<String,SBQQ__QuoteLine__c>();
      SBQQ__QuoteLine__c[] lines = [SELECT SBQQ__Product__r.SBQQ__SubscriptionCategory__c, SBQQ__Product__r.SBQQ__SubscriptionTerm__c,
                            SBQQ__Product__r.Service_Level__c, SBQQ__Product__r.Term_Type__c, SBQQ__Quote__c
                           FROM SBQQ__QuoteLine__c
                           WHERE SBQQ__Quote__c IN :changedServiceLevel AND SBQQ__SubscriptionPricing__c != null];
      for (SBQQ__QuoteLine__c line : lines) {
        SBQQ__Quote__c old = oldMap.get(line.SBQQ__Quote__c);
        SBQQ__Quote__c quote = quotesById.get(line.SBQQ__Quote__c);
        if (line.SBQQ__Product__r.Service_Level__c == old.Service_Level__c) {
          String key = generateKey(line, quote.Service_Level__c);
          Product2 newMaint = productsByKey.get(key);
          System.assert(newMaint != null, 'No product: ' + key);
          if (newMaint != null) {
            line.SBQQ__Product__c = newMaint.Id;
            line.SBQQ__SubscriptionPercent__c = newMaint.SBQQ__SubscriptionPercent__c;
            line.SBQQ__SubscriptionPricing__c = newMaint.SBQQ__SubscriptionPricing__c;
      update lines;

  private String generateKey(SBQQ__QuoteLine__c line) {
    return generateKey(line, line.SBQQ__Product__r.Service_Level__c);

  private String generateKey(SBQQ__QuoteLine__c line, String serviceLevel) {
    return line.SBQQ__Product__r.SBQQ__SubscriptionCategory__c + '-' + line.SBQQ__Product__r.Term_Type__c + '-' + line.SBQQ__Product__r.SBQQ__SubscriptionTerm__c + '-' + serviceLevel;

  private String generateKey(Product2 product) {
    return product.SBQQ__SubscriptionCategory__c + '-' + product.Term_Type__c + '-' + product.SBQQ__SubscriptionTerm__c + '-' + product.Service_Level__c;

  testMethod static void test() {
    Product2 p1 = new Product2(Name='Test1',Service_Level__c='Test',SBQQ__SubscriptionPricing__c='Percent Of Total');
    Product2 p2 = new Product2(Name='Test1',Service_Level__c='TestPlus',SBQQ__SubscriptionPricing__c='Percent Of Total');
    insert new Product2[]{p1,p2};

    Account customer = new Account(Name='Test',BillingCountry='USA',Industry='Software');
    insert customer;

    Opportunity opp = new Opportunity(Name='Test',AccountId=customer.Id,CloseDate=System.today(),StageName='Prospecting');
    insert opp;

    SBQQ__Quote__c quote = new SBQQ__Quote__c(SBQQ__Opportunity__c=opp.Id,Service_Level__c='Test');
    insert quote;

    SBQQ__QuoteLine__c line = new SBQQ__QuoteLine__c(SBQQ__Quote__c=quote.Id,SBQQ__Product__c=p1.Id);
    insert line;

    quote.Service_Level__c = 'TestPlus';
    update quote;

It looks like you have a trigger "CustomQuoteAfter" that calls this class? If so, remove the reference from the trigger.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.