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
wcwill978wcwill978 

Create custom object on opportunity after update

Hi I created a custom object called Win_Loss_Analysis__c within the opportunity and am trying to create a trigger that will automatically create a new analysis after the Opportunity is Stage is set to closedwon. The Field name of the stage field is: StageName.

 

Can someone please guide me in the right direction on how will this appex trigger look or how to get it started I really apreciate it, I'm new to Apex and am trying to learn. The object Win_Loss_Analysis__c has multiple page layouts and record types so basically when a user sets the opportunity stage to close lost we have a required dependent field called Loss Analysis with three values (Price, Product feature, relationship) based on the value they choose we have pagelayouts tied to record types that determine which values will show.

 

I just want the Win_Loss_Analysis__c to automatically create when these fields are updated based on the choices the user picked and then we will have workflow tied to the Win_Loss_Analysis__c to send an email to the opportunity owner reminding them to complete the Win_Loss_Analysis__c.

 

Any help will be appreciated, thank you

AhmedPotAhmedPot

May be this can get you started.

 

trigger DeviationCreate on Opportunity(after insert, after update) {
    Map<Id,Win_Loss_Analysis__c> mapRec = new Map<Id,Win_Loss_Analysis__c>();


    for(RecordType r: [Select r.Name, r.Id From RecordType r where r.SobjectType = "Win_Loss_Analysis__c"]){
        mapRec.put(r.name,r.id)
    }
    List<Win_Loss_Analysis__c> lstWinLoss = new List<Win_Loss_Analysis__c>();

    for(Opportunity Loan:Trigger.New){
        
        if(opp.stageName ='close'){
            Win_Loss_Analysis__c wl = new Win_Loss_Analysis__c();
            if(mapRec.containsKey(opp.Loss_Analysis__c)){ // if your record type name of Win_Loss_Analysis__c object is same as values in picklist
                wl.o.RecordTypeId = mapRec.get(opp.Loss_Analysis__c)
            }
            //set any other field needed
            lstWinLoss.add(wl);
        }
        
    }
    if(lstWinLoss.size()>0)
        insert lstWinLoss;
}

 

 

wcwill978wcwill978

Hi and thanks for all your help so far I tried adding this into the trigger:

 

trigger AutoCreateWinLossAnalysis on Opportunity (after update, after insert) {
Map<ID,Win_Loss_Analysis__c> mapRec = new Map<ID,Win_Loss_Analysis__c>();
    for(RecordType r: [Select r.Name, r.ID From RecordType where r.SobjectType = "Win_Loss_Analysis__c"]){
        mapRec.put(r.Name,r.ID)
    }
    List<Win_Loss_Analysis__c> lstWinLoss = new List<Win_Loss_Analysis__c>();
    for(Opportunity Loan:Trigger.New){
        if(StageName =='Closed Lost'){
            Win_Loss_Analysis__c wl = new Win_Loss_Analysis__c();
            if(mapRec.containsKey(opp.Loss_Analysis__c)){
                wl.o.RecordTypeId = mapRec.get(opp.Loss_Analysis__c)
            }
            
            lstWinLoss.add(wl);
        }
        
    }
    if(lstWinLoss.size()>0)
        insert lstWinLoss;
}

 

and get the following error: Error: Compile Error: line 3:81 no viable alternative at character '"' at line 3 column 81.

 

I am not sure what this means if it makes any sense the record types I have are in the custom object themselves so when the opportunity is closed and the LossAnalysis dependent field is set to either Price, Relationship, etc. a different page layout is attched to them. I just want the trigger to create the new custom object when the Opportunity is marked Closed Lost in the Satge field.

AhmedPotAhmedPot

Sorrry I typed the code in notepad, so it might have some syntax errors. the select query in line 3 has double quotes (") in where clause. just replace them with single quote.

 

If your picklist value and record type values are same, then this should work without any change.

 

I would advise you to check the logic and it according to your requirement.

 

Thanks,

Ahmed

wcwill978wcwill978

Hi Ahmed,

 

I got the trigger working correctly now and have tested it and its working as it should (below is what we have). Before I deploy this into Production I've read that we need to create a test class, how will I go about doing this? Can you please help me with creating it so i can get at least 75% coverage:

 

 

trigger AutoCreateWinLossAnalysisOnOpportunityCSL on Opportunity (after update) 
{

  List<Opportunity> closedOps = new List<Opportunity>();
  List<Win_Loss_Analysis__c> newwinLossObjects = new List<Win_Loss_Analysis__c>();  
  List<Win_Loss_Analysis__c> updatewinLossObjects = new List<Win_Loss_Analysis__c>();
  
  List<RecordType> recordTypesForOppty = new List<RecordType>();
  recordTypesForOppty = [Select Name, ID From RecordType where SobjectType = 'Win_Loss_Analysis__c'];
    List<Id> ExistingIds = new List<Id>();
    
     
    Integer  count = Trigger.new.size(); 
    for(Opportunity newvalue : Trigger.new)
    {
      Opportunity oldvalue = Trigger.oldMap.get(newvalue.Id);
        if(oldvalue.StageName != newvalue.StageName || oldvalue.Loss_Analysis__c != newvalue.Loss_Analysis__c)  
       {
           if(newvalue.StageName == 'Closed Lost'){
            if(newvalue.Loss_Analysis__c == 'Price' 
              || newvalue.Loss_Analysis__c == 'Product Feature/Functionality' 
              || newvalue.Loss_Analysis__c =='Relationship')
            {
               closedOps.add(newvalue);
                 ExistingIds.add(newvalue.Id);
       
            }
          }
       }
    }
    system.debug('Found : ' + closedOps.size() + ' Opps that need analysis records created');
    if (closedOps.size() > 0)  
    { 
      List<Win_Loss_Analysis__c> existing = [SELECT Id,Opportunity_Name__c FROM Win_Loss_Analysis__c WHERE  Opportunity_Name__c  in :ExistingIds];
      system.debug('Found : ' + existing.size() + ' Existing Win Loss Records');
      string LossAnalysis = null;
      for (Opportunity oppty : closedOps)
      {       
              // get the recordTypeId
              Id WinLossObjectRecordTypeId = null;
              string typeName;
              LossAnalysis = oppty.Loss_Analysis__c.toLowerCase();
          for (RecordType recordType : recordTypesForOppty)
          {
            typeName = recordType.Name.toLowerCase();
            if (LossAnalysis == 'price' && typeName == 'price') 
            {
              WinLossObjectRecordTypeId = recordType.Id;
            }
            if (LossAnalysis == 'product feature/functionality' && typeName == 'productfeature') 
            {
              WinLossObjectRecordTypeId = recordType.Id;
            }
            if (LossAnalysis == 'relationship' && typeName == 'relationship') 
            {
              WinLossObjectRecordTypeId = recordType.Id;
            }
          }
          system.debug('Record type id: ' + WinLossObjectRecordTypeId + ' found for oppt id' + WinLossObjectRecordTypeId );
              // construct the new custom object with the required fields set
              
              Win_Loss_Analysis__c wL = new Win_Loss_Analysis__c();
              wL.Opportunity_Name__c = oppty.Id;
              wL.RecordTypeId = WinLossObjectRecordTypeId;
              wL.Account_Name__c = oppty.AccountId;
              if(existing.size() > 0)
              {
                   for(Win_Loss_Analysis__c exist : existing)
                {
                  if(exist.Opportunity_Name__c == oppty.Id)
                  {
                    wL.Id = exist.Id;
                    break;  
                  }              
                }
              }
              
              if(wL.Id == null)
              {
                newwinLossObjects.add(wL);
              }
              else
              {
                updatewinLossObjects.add(wL);
              }
              
      }
    }
    system.debug('Inserting ' + newwinLossObjects.size() + ' new Win Loss Objects' );
    system.debug('Updating ' + updatewinLossObjects.size() + '  Win Loss Objects' );
    if(newwinLossObjects.size() > 0)
         insert newwinLossObjects;
   
    if(updatewinLossObjects.size() > 0)
         update updatewinLossObjects;

}
roysmith601.3493067652527424E1roysmith601.3493067652527424E1

I have to add event record type to my trigger. for example, if user click on event(activity related list) in opportunity object  and we have 4 record type but we want  this functionlaity to work for only one event record type and its only work for one record  type = Opportunity Event  .

 

I enter the if statement but i am getting the following error:

Error: Compile Error: Variable does not exist: t.Subject at line 4 column 5

 

my trigger is as follow:

 

trigger eventafter on Event (after insert,after update) {
List<Opportunity> opps = new List<Opportunity>{};

if (t.Subject != null && t.WhatId.getSObjectType() == Opportunity.sObjectType && t.RecordType.Name = 'Opportunity Event')


if(trigger.isInsert)
{
for (Event t : trigger.new)
{
if (t.Subject != null && t.WhatId.getSObjectType() == Opportunity.sObjectType)
{
opps.add(new Opportunity(Id = t.WhatId, StageName = t.Subject));
}
}
}
else
{
for(Event t : trigger.new)
{
if(t.Subject != null
&& t.WhatId.getSObjectType() == Opportunity.sObjectType
&& t.Subject != trigger.oldMap.get(t.Id).Subject)
{
opps.add(new Opportunity(Id = t.WhatId, StageName = t.Subject));
}

}
}

if(opps != null && !opps.isEmpty()){
Database.update(opps);
}
}

 

 Please help that why i am getting this error and how can i reslove this.Also,If i have to use this for Bulk record then how can i use that in my current trigger.

i m new to salesforce so please help me

thanks