+ Start a Discussion
Mariappan PerumalMariappan Perumal 

trigger for bulk process

Hi all, 

 

I have written a trigger on opportunity , whenever a record created on opportunity whose campaignId and Are you donor or vendor(custom field) is vendor.

 

Then Fields updates will be in custom object (junction object which will relate campaign and accoun ).

 

I don't whether my trigger work properly or not.

 

The doubt is I got the id of campaignId and AccountId in opportunity and put in a set and doing the process and there were no relationship between those set . 

 

can anyone tell me whether my trigger properly or not..

 

trigger VendorAmount on Opportunity (before insert) 
{
set<ID> cids = new set<ID>();
set<ID> aids = new set<ID>();
for (Opportunity t : trigger.new)
{
if (t.CampaignId!= null && t.Are_you_Donor_Vendor__c=='Vendor' )
cids.add(t.CampaignId);
aids.add(t.AccountId);
}
List<CampaignVendor__c> cv=[Select id, Campaign__c,vendoramount__c From CampaignVendor__c where Campaign__c =:cids and Account__c=:aids ];
for (Opportunity t : trigger.new)
{
 for(CampaignVendor__c cc:cv)
    {
    cc.vendoramount__c= t.Amount ;
    update cc;
    }
   
 }
}

 

 

pjcloudpjcloud

It is hard to say everything that you will need to do to get this trigger working, but there are some clear problems you will need to resolve: 

 

  1. Are you intending to do a complete replace on the existing value in the junction object record? Or do you want to increment?
  2. Performing an update (or insert, delete, etc.) in the middle of a loop will incur governor limit exceptions and is one of the most common anti-patterns in Apex Triggers. You need to martial up your updates into a new list and then update the entire list. 
  3. Your query will retrieve all records that have a campaign and an account in common with the campaign and account in the Opportunity, but there is no way that I can see based on what you've shared so far to map the CampaignVendor__c record back to one single opportunity...or vice-versa. 

To elaborate on number 2, here's the pattern you need to look at: 

 

trigger VendorAmount on Opportunity (before insert) 
{
List<CampaignVendor__c> cvList = new List<CampaignVendor__c>();
...collect data to perform the query I want...
List<CampaignVendor__c> cv=[...do my query...]; for(CampaignVendor__c cc:cv){
if (...check to see if I want this campaign vendor...){ cc.vendoramount__c= t.Amount ; cvList.add(cc); } }
update cvList; }

It is important to remember that both query statement and DML statements are purposefully very limited in Apex to prevent a type of performance problem that could be characterized as "death by a thousand paper cuts" where you make too many trips to the DB. So if you're working with many records (which is always the case with triggers) it is important to collect up the stuff you want to invoke your SOQL only once (which you did) and your DML (which you didn't) only once. 

 

To elaborate on number 3:

 

If I have three opportunities: 

Opp 1: Account: Acme, Campaign: 1

Opp 2: Account: Acme, Campaign: 1

Opp 3: Account: Acme, Campaign: 1

 

If all three of these opportunities appear in your Trigger.new set, how do you intend to handle that there are three opportunities that point to the same Account/Campaign intersection. 

 

Another Example: 

CampaignVendor__c 1: Account: Acme, Campaign: 1

CampaignVendor__c 2: Account: Acme, Campaign: 1

CampaignVendor__c 3: Account: Acme, Campaign: 1

 

Opp 1: Account: Acme, Campaign 1

 

If the trigger executes on this Opportunity 1, which of the above CampaignVendor__c records is to be updated? Is it all of them? 

 

This is the more troubling problem, and as I contemplated your code to see if I could do a rewrite to help you, this is where I came to the sticking point that we don't know enough information about how CampaignVendor__c relates to Opportunity to be able to make your trigger work. My inclination is to ask, are you over-architecting here? If Opportunity is an intersection of Account and Campaign, and CampaignVendor__c is an intersection of the same, maybe you don't need the extra custom object at all, and could consider putting the custom field VendorAmount__c in the Opportunity object instead. If there should be a 1:1 relationship between Opportunity and CampaignVendor__c maybe you need a lookup from one to the other to establish the link between each Opportunity-CampaignVendor__c pairing. 

 

Maybe this gives you some food for thought to help clarify your goals for this trigger a bit. 

Mariappan PerumalMariappan Perumal

Hi .

 

Its really pleasant to hear from you.

For 1. It will update the vendoramount in campaign vendor (custom object ie . junction object)and there will be only one record with that combination on opportunity record ( ie. campaign and account as such in campaign vendor)

 

how i am gonna separate that is by ( campaign and account field and also with a custom field picklist (should be vendor here)

and definetly there may be several combination in bulk process in that case too.

 

For 2. The Solution is the exact correct one for that. unfortunately i forgot to put that in list and update . 

 

For 3 : 

If I have three opportunities: 

Opp 1: Account: Acme, Campaign: 1         

Opp 2: Account: Acme, Campaign: 1          These cases will be narrow down by custom picklist field and still confusion                  

Opp 3: Account: Acme, Campaign: 1              update with the latest record in campaign vendor object that exact    

 

 

                                                                                 combination in single record

 

If all three of these opportunities appear in your Trigger.new set, how do you intend to handle that there are three opportunities that point to the same Account/Campaign intersection. 

 

Another Example: 

CampaignVendor__c 1: Account: Acme, Campaign: 1

CampaignVendor__c 2: Account: Acme, Campaign: 1     These combination in campaign vendor will be exactly one.

CampaignVendor__c 3: Account: Acme, Campaign: 1

 

 

I know this sort of combination will come and create problem with my trigger . 

 

The point 2 is awesome and made to correct myself in future. 

 

The Trigger which i wrote with SOQL inside for loop and to remove that i wrote blindly with 2 set which will create lot of combinations. I have pasted the trigger below

 

trigger vendoramount on Opportunity (before insert)
{
for (Opportunity t : trigger.new)
{
if (t.CampaignId!= null & t.LeadSource=='Web' )
{

List<CampaignVendor__c> cv=[Select Campaign__c,vendoramount__c From CampaignVendor__c where Campaign__c =:t.CampaignId and account__c=:t.AccountId ];
for(CampaignVendor__c cc:cv)
{
cc.vendoramount__c= t.Amount ;
}
}
}
}
}

 

 

How can we map campaignId and accountId from same opportunity record to campaignvendor instead of putting separate set as i did in the first post . 

 

If you have any other also , let me know . and really really pleasant to hear from you. 

 

Nice to hear from you once again.