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
stefanodlstefanodl 

trigger to inser new opportunity

Hello,

 

I need to create a trigger in order to insert a new opportunity when a speficic condition is verified on existing opportunity.

 

The ruel should be the following:

 

IF Opp is Won and if Opp.NumberField < Acc.Number field THEN insert a new Opp with Type equals to Upsell.

 

Thanks for your help.

 

Stefano

Shashikant SharmaShashikant Sharma

Here is your trigger

 

 

trigger insertNewOpportunity on Opportunity (after insert, after update) {
List<Opportunity> listOppor = new List<Opportunity>();
for(Opportunity opp : Trigger.new)
{
   
   //Please update number api name of opp.NumberField  and opp.Account.AccountNumber as  per your requirement
   if(opp.StageName == 'Won' && opp.Account != null && opp.NumberField < opp.Account.AccountNumber)
       {
          Opportunity oppNew = opp.clone(false);
          oppNew.Type = 'Upsell';
          listOppor.add(oppNew);
       }
    if(listOppor.size() > 0)
     insert listOppor;    
   
}

}

 

 

Ankit AroraAnkit Arora

I am not sure as I have not implemented this, but is there any stage name "Won" ???

And I also hope you have tested this trigger and it is not creating any cascading???

 

 

Thanks
Ankit Arora

 

Shashikant SharmaShashikant Sharma

Please update any API Name or value as pre your requirement, I used API Name and values from ur post.

Shashikant SharmaShashikant Sharma

 

To avoid casecading : means trigger invoke trigger in chain
trigger insertNewOpportunity on Opportunity (after insert, after update) {
List<Opportunity> listOppor = new List<Opportunity>();
for(Opportunity opp : Trigger.new)
{
   
   //Please update number api name of opp.NumberField  and opp.Account.AccountNumber as  per your requirement
   if(opp.StageName == 'Won' && opp.Account != null && opp.NumberField < opp.Account.AccountNumber)
       {
          Opportunity oppNew = opp.clone(false);
          oppNew.Type = 'Upsell';
          //By chaning status you will by pass trigger for newly created opportunity
          //Some StageName except the one used in entry condition (Won in your case)
          oppNew.StageName = 'OtherStageName';
          listOppor.add(oppNew);
       }
    if(listOppor.size() > 0)
     insert listOppor;    
   
}
}

 

 

 

Ankit AroraAnkit Arora

Now that's looks good to me, good work  Shashikant.

 

 

Thanks
Ankit Arora

 

Shashikant SharmaShashikant Sharma

One more change in trigger

 

Take this out side the for loop.

 

 

if(listOppor.size() > 0)
     insert listOppor;   

 

stefanodlstefanodl

Hello Ankit,

 

thanks a lto for your help!

 

I changed name of fields to the correct ones and i tried to run a test, but the test is not covering the following part:

 

 9   Opportunity oppNew = opp.clone(false);
 10   oppNew.Type = 'Upsell';
 11   //By chaning status you will by pass trigger for newly created opportunity
 12   //Some StageName except the one used in entry condition (Closed Won in your case)
 13   oppNew.StageName = 'OtherStageName';
 14   listOppor.add(oppNew);
 15   }
 16   if(listOppor.size() > 0)
 17   insert listOppor;

 

Can you pplease explain me what does the line 9 mean (opp.clone(false)) ?

 

Also, no Opportynity is created after the conditions are verified.

Am I missing something?

 

Many thanks,

Stefano

 

 

 

Shashikant SharmaShashikant Sharma

Clone false means creating a clone of the record which will hav same field values as the record we are cloning. false in parameter will remove id from the new cloned record as we want to insert a new oppor tunity record with new id.

stefanodlstefanodl

Hello,

 

thanks for your explanation.

 

Unfortunately, th trigger is not working. Here is the updated trigger:

 

 

 

trigger insertNewOpportunity on Opportunity (after insert, after update) {
List<Opportunity> listOppor = new List<Opportunity>();
for(Opportunity opp : Trigger.new)
{
   
     if(opp.StageName == 'Closed Won' && opp.Account != null && opp.N_Of_Hotels_Payed__c < opp.Account.N_of_Hotels__c)
       {
          Opportunity oppNew = opp.clone(true);
          oppNew.Type = 'Upsell';
          //By chaning status you will by pass trigger for newly created opportunity
          //Some StageName except the one used in entry condition (Closed Won in your case)
          oppNew.StageName = 'Contract Sent';
          listOppor.add(oppNew);
       }
    if(listOppor.size() > 0)
     insert listOppor;    
   
}
}

 And this is the Test:

 

 

/**
 * This class tests the trigger named AddCampaign.
 */
@isTest
private class UpsellOppTest {

    static testMethod void UpsellOppTest() {       
                    
        //Data Prep
        
        //Create Account, Opportunity, Product, etc.
        Account acct1 = new Account(name='test Account One1');
        acct1.Type = 'Chain';
        acct1.N_of_Hotels__c = 10;
        insert acct1;
        
        //Create Opportunity on Account
        Opportunity Oppty1 = new Opportunity(name='test Oppty One1');
        Oppty1.AccountId = acct1.Id;
        Oppty1.StageName = 'Closed Won';
        Oppty1.CloseDate = Date.today();
        
        insert Oppty1;   
        
         //Create Opportunity on Account
        Opportunity Oppty2 = new Opportunity(name='test Oppty One2');
        Oppty2.AccountId = acct1.Id;
        Oppty2.StageName = 'Contract Sent';
        Oppty2.CloseDate = Date.today();
        
       
        insert Oppty2;              
                        
       // Create Products 
         Product2 testprod1 = new Product2 (name='TRIAL');
         testprod1.productcode = 'TRL';
         insert testprod1;
         
         Product2 testprod2 = new Product2 (name='ADVANCED');
         testprod2.productcode = 'ADV';
         insert testprod2;

// Ger Pricebook
         Pricebook2 testpb = [select id from Pricebook2 where IsStandard = true];   

// Add to pricebook
         PricebookEntry testpbe1 = new PricebookEntry ();
         testpbe1.pricebook2id = testpb.id;
         testpbe1.product2id = testprod1.id;
         testpbe1.IsActive = True;
         testpbe1.UnitPrice = 250;
         testpbe1.UseStandardPrice = false;
         insert testpbe1;
         PricebookEntry testpbe2 = new PricebookEntry ();
         testpbe2.pricebook2id = testpb.id;
         testpbe2.product2id = testprod2.id;
         testpbe2.IsActive = True;
         testpbe2.UnitPrice = 250;
         testpbe2.UseStandardPrice = false;
         insert testpbe2;
         
         
                //And now you want execute the startTest method to set the context 
                //of the following apex methods as separate from the previous data 
                //preparation or DML statements.  
        test.starttest();
        
          // add the line item which should call the trigger
          // with this line item it should fail out quickly 
          // As Auto Schedule is false
    OpportunityLineItem oli1 = new OpportunityLineItem();
    oli1.Quantity = 1;
    oli1.Months__c = 12;
    oli1.TotalPrice = 1;
    oli1.PricebookEntryId = testpbe1.id;
    oli1.OpportunityId = oppty1.id;    
    insert oli1;   
    
            
          // add the line item which should call the trigger
          // Auto Schedule is true so it should build the schedule.
    OpportunityLineItem oli2 = new OpportunityLineItem();
    oli2.Quantity = 2;
    oli2.Months__c = 12;
    oli2.TotalPrice = 1;
    oli2.PricebookEntryId = testpbe2.id;
    oli2.OpportunityId = oppty1.id;    
    insert oli2;
     
         
    
           
        test.stoptest();
    }
}

 

Test is covering only 44% and Trigger is not inserting and Opportunity.

What's wrong according to you?

 

Many thanks in advance.

Stefano

 

 

 

 

 

_Prasu__Prasu_

I guess trigger must be failing as you are using the field "opp.Account.N_of_Hotels__c" which is from Account.

 

This field would not be directly accesible from the opp record in trigger. you will need to make a query on the Account and bring correesponding Accounts and then use them while comparing.

 

Make sure you dont make a query on Account in loop. As previosuly post said, make DML action out of loop.

stefanodlstefanodl

I've created a new formula field in Opportunitty recalling the same field from Account, but still not working.

Also, I've added "Update Oppty1 and Update Oppty2 in the apex classs, and test covering is always 44%.

 

It's really strange.

 

 

stefanodlstefanodl

Hello,

 

at the end the trigger now it's working!

 

thanks,

 

Stefano

_Prasu__Prasu_

What was the issue?

Barbara1.3649760384938914E12Barbara1.3649760384938914E12

HI,

 

I've tweaked and activate the following trigger:

 

 trigger insertNewRevenue on Opportunity (after update) {

List<Opportunity> listOppor = new List<Opportunity>();
for(Opportunity opp : Trigger.new)
{
   
   //Please update number api name of opp.NumberField  and opp.Account.AccountNumber as  per your requirement
   if(opp.StageName == 'closed Won')
       {
          Opportunity oppNew = opp.clone(false);
          oppNew.Type = 'Upsell';
          //By chaning status you will by pass trigger for newly created opportunity
          //Some StageName except the one used in entry condition (Won in your case)
          oppNew.StageName = 'Forecasted';
          oppNew.Name = 'TO BE UPDATED';
          listOppor.add(oppNew);
       }
    if(listOppor.size() > 0)
     insert listOppor;    
   
}
}

 

It's look ok, but I would like to automatically change the closing date to the following month.

Today all opportunity close date is the last day of the month, so when it create a new opp upon closing the current one, I need to have the closing date updated to the following month.

 

Any idea how to do it ?

 

Thanks

Barbara

 

Also I did not understand this part of the triger : && opp.Account != null && opp.NumberField < opp.Account.AccountNumber)

So i deleted it. I hope it's okay