function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
NiccoleNiccole 

Trigger new Case based on value in an Oppty field

Hi there,

I am trying to trigger a new case to be created when a custom field (Quote Status) on my opportunity has the value "Quote Approval".  See screen shot for further field info, if needed.  

Since I am new to Apex and Triggers, I found and modified some code.  (Original Code found on https://developer.salesforce.com/forums/ForumsMain?id=906F0000000942YIAQ  (https://developer.salesforce.com/forums/ForumsMain?id=906F0000000942YIAQ) )  My modified code is throwing an error message "Error: Compile Error: Invalid foreign key relationship: Opportunity.Quote_Status_v2__c at line 4 column 109".  When I deleted the "opp." from "opp.Quote_Status_v2__c", I then received the following error message "Error: Compile Error: Variable does not exist: Quote_Status_v2__c.equals at line 4 column 105".

Can someone tell me what I am doing wrong and how to fix it.  If it is possible to correct my trigger, I would greatly appreciate it :)!

My trigger:

trigger SEApproveRejectQuoteTaskCaseCreation on Opportunity (after insert,after update) {
        for (Opportunity opp: Trigger.New)
    { case newcase=new case();
         if((trigger.isInsert && (opp.Quote_Status_v2__c.equals('Quote Approval'))) || (trigger.isUpdate &&(opp.Quote_Status_v2__c.equals !=  Trigger.oldMap.get(opp.Id).Quote_Status_v2__c && opp.Quote_Status_v2__c.equals('Quote Approval'))))
         {
            system.debug('----------opp.Account---->'+opp.Account);
            newcase.Account=opp.Account;
            newcase.Opportunity__c=opp.Name;
            newcase.Subject='Approve / Reject Quote for '+opp.Name;
            newcase.Description='Quote approval is needed for '+opp.Name;
            newcase.Status='New';
            newcase.Origin='End User Request';
            newcase.Priority='Low';
            newcase.Task_Steps__c='1. Review Quote \n2. Approve / Reject Quote \n3. Complete case in Salesforce';
         }}}


User-added image

Best Answer chosen by Niccole
NiccoleNiccole
This may not work for everyone, but I ended up having to write an Apex Class for this, along with a trigger (best practice).  Note that the code below will generate 2 cases at the same time when the Quote Status = Quote Approval.  It will also re-assign the Case Owner to be a certain user based on two custom fields on the Opportunity object. 

Trigger:

trigger Opportunity_OnAfterUpsert on Opportunity (after insert, after update)
{
   OpportunityRecord toUpsert = new OpportunityRecord();

   Integer count = 0;
   for(Opportunity o: Trigger.new)
   {
      Opportunity old = null;
      if(System.Trigger.oldMap != null) old = System.Trigger.oldMap.get(o.ID);
      toUpsert.OnAfterUpsert(o, old);
   }
}

Apex Class:

public class OpportunityRecord
{
   public void OnAfterUpsert(Opportunity toUpsert, opportunity old)
   {
      this.UpsertNewCaseOnQuoteApproval(toUpsert, old);
      this.UpsertCaseAssignment(toUpsert);
   }
  
   private void UpsertNewCaseOnQuoteApproval (Opportunity toUpsert, opportunity old)
{
   if(old != null && old.Quote_Status_v2__c != toUpsert.Quote_Status_v2__c)
   {

        List<case> caseList = new List<case>(); 
        If(toUpsert.Quote_Status_v2__c=='Quote Approval')
        {
                Case c= new Case();
                c.Status='New';
                c.Reason='Approve / Reject Quote';
                c.Origin='End User Request';
                c.Priority='Low';
                c.Type='SE Support';
                c.Subject='Approve / Reject Quote for '+toUpsert.Name;
                c.Description='Quote approval is needed';
                c.Task_Steps__c='1. Change this Case status to "In Progress" \n2. Review Quote \n3. Approve or Reject Quote \n4. Change this Case status to "Closed"';
                c.Accountid=toUpsert.Accountid;
                c.Opportunity__c=toUpsert.id;
                c.Opportunity_Owner__c=toUpsert.ownerid;
                caseList.add(c);

                c= new Case();
                c.Status='New';
                c.Reason='Space Reservation';
                c.Origin='End User Request';
                c.Priority='Low';
                c.Type='SE Task';
                c.Subject='Link space reservation(s) for '+toUpsert.Name;
                c.Description='Space reservation(s) need to be linked to Quote';
                c.Task_Steps__c='1. Change this Case status to "In Progress" \n2. Link space reservation(s) to Quote \n3. Change this Case status to "Closed"';
                c.Accountid=toUpsert.Accountid;
                c.Opportunity__c=toUpsert.id;
                c.Opportunity_Owner__c=toUpsert.ownerid;
            
                caseList.add(c);
        }    
           if (caseList.size()>0) insert caseList;
  }
}
        public void UpsertCaseAssignment(Opportunity toupsert)
        {
            List<case> caseList = [select OwnerId from Case where Opportunity__c = :toupsert.id limit 200];
            for(Case c: caseList)
            {    
                //if oppty's alternate SE is set and is different from the case owner, set case owner to oppty alt SE
                //else if oppty's SE is different from case owner, set case owner to oppty SE
                if(toupsert.Lead_Sales_Engineer__c != null && toupsert.Lead_Sales_Engineer__c != c.ownerid)
                    c.ownerid = toupsert.Lead_Sales_Engineer__c;
              else if (toupsert.Lead_Sales_Engineer_for_Site__c != null &&
              toupsert.Lead_Sales_Engineer_for_Site__c != c.ownerid)
                    c.ownerid = toupsert.Lead_Sales_Engineer_for_Site__c;
            }
            update caseList;
          }
            
}

All Answers

NehalNehal (Salesforce Developers) 
Hi,

Please review the below sample trigger code and modify it accordingly.

trigger NewCase on Opportunity (before insert, before update) {

for(Opportunity o: Trigger.new){
If(o.QuoteStatus__c=='Quote Approval'){

Case c= new Case();
c.Status='workin';
c.Origin='web';
c.Account=o.Account;

insert c;
}

}

}

I hope this helps.

Please mark this as a "Best Answer" if this has resolved your issue.
NiccoleNiccole
Thank you Nehal that worked.  

However, some other issues appeared.  In the trigger I had the following line "c.Opportunity__c=o.Name;".  When the Quote Status field is populated with Quote Approval I received the following error "Error:Apex trigger NewSECaseQuoteApproval caused an unexpected exception, contact your administrator: NewSECaseQuoteApproval: execution of BeforeUpdate caused by: System.StringException: Invalid id: Nicc test 2: Trigger.NewSECaseQuoteApproval: line 16, column 1"

Thus, I edited and removed the "c.Opportunity__c=o.Name;" from the trigger to see if it would create the case and it did.  But, when I went to the case, I noticed that my "Account Name" field on the case wasn't populated with any information.  Please note that on the Oppty the "Account Name" and "Oppty Name" fields, which are the standard Oppty fields, are populated.

Are you able to help me out with populating the "Opportunity" and "Account Name" fields on the case object with the Opportunity info?  Appreciate all your help :)!

Case Object Fields Info:
  • Account Name
    • standard field
    • data type = Lookup(Account)
  • Opportunity
    • custom field
    • data type = Lookup Field
    • API Name = Opportunity__c
    • related to =  oppty
    • related list label = cases
    • child relationship name = cases
    • required = no
    • no validation rules apply to this field

Trigger:
trigger NewSECaseQuoteApproval on Opportunity (before insert, before update) {

for(Opportunity o: Trigger.new){
If(o.Quote_Status_v2__c=='Quote Approval'){

Case c= new Case();
c.Status='New';
c.Reason='Approve / Reject Quote';
c.Origin='End User Request';
c.Priority='Low';
c.Type='SE Task';
c.Subject='Approve / Reject Quote for '+o.Name;
c.Description='Quote approval is needed';
c.Task_Steps__c='1. Change this Case status to "In Progress" \n2. Review Quote \n3. Approve or Reject Quote \n4. Change this Case status to "Closed"';
c.Account=o.Account;
c.Opportunity__c=o.Name;

insert c;
}

}

}
NiccoleNiccole
Sorry, forgot to mention / ask, but do you also know how to change the case owner to be a specific queue when it is created?  
NehalNehal (Salesforce Developers) 
Hi,

Please change the below line 

c.Account=o.Account; to below

c.Accountid=o.Accountid;

I hope this helps.

Please mark this as a "Best Answer" if this has resolved your issue.


NiccoleNiccole
Thanks agian Nehal!  Do you have an idea about the custom field "Opportunity" not populating and a way to change the case owner to a queue when it is created?
NehalNehal (Salesforce Developers) 
Hi,

Kindly do the following to populate custom field "Opportunity": 

c.Opportunity__c=o.id;

For changing the case owner to a queue , I would have to check that.
NiccoleNiccole
This may not work for everyone, but I ended up having to write an Apex Class for this, along with a trigger (best practice).  Note that the code below will generate 2 cases at the same time when the Quote Status = Quote Approval.  It will also re-assign the Case Owner to be a certain user based on two custom fields on the Opportunity object. 

Trigger:

trigger Opportunity_OnAfterUpsert on Opportunity (after insert, after update)
{
   OpportunityRecord toUpsert = new OpportunityRecord();

   Integer count = 0;
   for(Opportunity o: Trigger.new)
   {
      Opportunity old = null;
      if(System.Trigger.oldMap != null) old = System.Trigger.oldMap.get(o.ID);
      toUpsert.OnAfterUpsert(o, old);
   }
}

Apex Class:

public class OpportunityRecord
{
   public void OnAfterUpsert(Opportunity toUpsert, opportunity old)
   {
      this.UpsertNewCaseOnQuoteApproval(toUpsert, old);
      this.UpsertCaseAssignment(toUpsert);
   }
  
   private void UpsertNewCaseOnQuoteApproval (Opportunity toUpsert, opportunity old)
{
   if(old != null && old.Quote_Status_v2__c != toUpsert.Quote_Status_v2__c)
   {

        List<case> caseList = new List<case>(); 
        If(toUpsert.Quote_Status_v2__c=='Quote Approval')
        {
                Case c= new Case();
                c.Status='New';
                c.Reason='Approve / Reject Quote';
                c.Origin='End User Request';
                c.Priority='Low';
                c.Type='SE Support';
                c.Subject='Approve / Reject Quote for '+toUpsert.Name;
                c.Description='Quote approval is needed';
                c.Task_Steps__c='1. Change this Case status to "In Progress" \n2. Review Quote \n3. Approve or Reject Quote \n4. Change this Case status to "Closed"';
                c.Accountid=toUpsert.Accountid;
                c.Opportunity__c=toUpsert.id;
                c.Opportunity_Owner__c=toUpsert.ownerid;
                caseList.add(c);

                c= new Case();
                c.Status='New';
                c.Reason='Space Reservation';
                c.Origin='End User Request';
                c.Priority='Low';
                c.Type='SE Task';
                c.Subject='Link space reservation(s) for '+toUpsert.Name;
                c.Description='Space reservation(s) need to be linked to Quote';
                c.Task_Steps__c='1. Change this Case status to "In Progress" \n2. Link space reservation(s) to Quote \n3. Change this Case status to "Closed"';
                c.Accountid=toUpsert.Accountid;
                c.Opportunity__c=toUpsert.id;
                c.Opportunity_Owner__c=toUpsert.ownerid;
            
                caseList.add(c);
        }    
           if (caseList.size()>0) insert caseList;
  }
}
        public void UpsertCaseAssignment(Opportunity toupsert)
        {
            List<case> caseList = [select OwnerId from Case where Opportunity__c = :toupsert.id limit 200];
            for(Case c: caseList)
            {    
                //if oppty's alternate SE is set and is different from the case owner, set case owner to oppty alt SE
                //else if oppty's SE is different from case owner, set case owner to oppty SE
                if(toupsert.Lead_Sales_Engineer__c != null && toupsert.Lead_Sales_Engineer__c != c.ownerid)
                    c.ownerid = toupsert.Lead_Sales_Engineer__c;
              else if (toupsert.Lead_Sales_Engineer_for_Site__c != null &&
              toupsert.Lead_Sales_Engineer_for_Site__c != c.ownerid)
                    c.ownerid = toupsert.Lead_Sales_Engineer_for_Site__c;
            }
            update caseList;
          }
            
}
This was selected as the best answer