+ Start a Discussion
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student 

Please help!! with trigger using cross-object criteria

Hey there,

I am trying to write some code which will update a related object of account. The code works perfectly normally, except i have re-qwritten it using criteria from a look-up related record.

Basiccally, the model goes:

Account - user adds a service (which is a child to account) and selects service_name and service_type.

Then a user adds a transaction when the client wishes to pay off the service.

When the transaction (which is also a child to account) is added, the transaction_type is set to 'First Payment' and the service lookup field is filled with a service that has its service_name as 'Essential property education only' and its service_type as 'New client'.

The first thing, is that the code works normally, with normal criteria. This is my attempt and it does not work:

trigger ClientPath_Transaction on Transaction__c (before insert) {
List<Account_Status__c> AccSt = new List<Account_Status__c>();
List<Account_Status__c> updatedAccSt = new List<Account_Status__c>();
List<Id> accIds = new List<Id>();


for (Transaction__c Tra: trigger.new) {
       if(Tra.Account__c != null && Tra.Transaction_Type__c == 'First Payment' && Tra.Destiny_Service_No__r != null) {
       accIds.add(Tra.Account__c);
       }
       }
  AccSt = [Select Id,Account_Status__c from Account_Status__c WHERE Account__c in :accIds];
  for(Account_Status__c a : AccSt)
  {
  

  
for (Transaction__c Tra: trigger.new) {   
if(Tra.Destiny_Service_No__r.Service_Name__c == 'Essential Property Education Only') {
       a.Account_Status__c = 'EPE Course Only';
       a.EPE_Course_Only__c = date.today();
    }

    
    
    }
       updatedAccSt.add(a);
       
}
if(updatedAccSt.size()>0)
{
update updatedAccSt;
}

}


Please help and thank you in advance for your time!
Ashish_SFDCAshish_SFDC
Hi Mikie, 


Tra.Destiny_Service_No__r This seems to be the problem, 

If it is a field on the related object it must be like this, 

Transaction__r.Related_Object__c.FieldName__c ; in case of custom. 

See below for the documentation,

http://www.salesforce.com/us/developer/docs/dbcom_soql_sosl/Content/sforce_api_calls_soql_relationships.htm


Regards,
Ashish



Eli Flores, SFDC DevEli Flores, SFDC Dev
Trigger.New only gives you the id,i.e.  Tra.Destiny_Service_No__c, to get the items from that record you have to query for them separately. 
So you'll have to gather all the Tra.Destiny_Service_No__c into a set, say  traserviceIDset, then throw services query into a map

something like 

map<id, service__c> servicesMap = new Map<id, Service__c>([Select id, Service_Name__c from Service__c where id in :traserviceIDset]);

then do the check like

if (servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Essential Property Education Only') {

It's tricky to remember this in the beginning because it doesn't throw an error. Everything off the main object (i.e.Tra.Destiny_Service_No__r.Service_Name__c) comes back but it just comes back as null instead of the expected value.
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
Thank you for your amazing explanation and code. I will attempt this and mark as solved once I get it. Thank you for your time
Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student

Hey ashish, I attempted your solution and was greeted with an error saying it was not a recognised variable. 

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
I got it saved, and it works...but my test is failing because it says that line 9 has too many SOQL querries. whch is weird as it only has one...? Please help

This is the finished code:
trigger ClientPath_Transaction on Transaction__c (After insert) {
List<Account_Status__c> AccSt = new List<Account_Status__c>();
List<Account_Status__c> updatedAccSt = new List<Account_Status__c>();
List<Id> accIds = new List<Id>();
 set<Id> traserviceIDset = new set<Id>();
 for (Transaction__c Tra : Trigger.new)
         traserviceIDset.add(Tra.Destiny_Service_No__c);

map<id, service__c> servicesMap = new Map<id, Service__c>([Select id, Service_Name__c, service_type__c from Service__c where id in :traserviceIDset]);


for (Transaction__c Tra: Trigger.New) {
       if(Tra.Account__c != null && (Tra.Transaction_Type__c == 'First Payment'||Tra.Transaction_Type__c == 'Refund')) {
       
       
       accIds.add(Tra.Account__c);
       }
       }
  AccSt = [Select Id,Account_Status__c from Account_Status__c WHERE Account__c in :accIds];
  for(Account_Status__c a : AccSt)
  {
  

  
for (Transaction__c Tra: Trigger.New ) {
//First Payment Services
//EPE Only
if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Essential Property Education Only' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client' && Tra.Transaction_Type__c == 'First Payment') {
       a.Account_Status__c = 'EPE Course Only';
       a.EPE_Course_Only__c = date.today();
    }
    //Adv New Client
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client'&& Tra.Transaction_Type__c == 'First Payment') {
       a.Account_Status__c = 'EPE Course: Advantage';
       a.EPE_Course_Advantage__c = date.today();
    }
    //Adv Upgrade from EPE
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Adv Upgrade EPE 1x New'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Adv Upgrade EPE 2x New')) {
       a.Account_Status__c = 'Support: Advantage';

    }
      //IPC New Client
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'First Payment' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client') {
       a.Account_Status__c = 'EPE Course: IPC';
       a.EPE_Course_IPC__c = date.today();
    }
    //IPC Upgrade from EPE
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'IPC Upgrade EPE 1x New'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'IPC Upgrade EPE 2x New')) {
       a.Account_Status__c = 'Support: IPC';
      
    }
    //Momentum Support Standard
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'First Payment' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Standard') {
       a.Account_Status__c = 'Support: Momentum';
       a.Support_Momentum__c = date.today();
    }
     //Momentum Support Plus
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus-Free')) {
       a.Account_Status__c = 'Support: Momentum Plus';
       a.Support_Momentum_Plus__c = date.today();
    }
    
    
    
//Refund Services
//EPE Only Refund
if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Essential Property Education Only' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund EPE Only';
       a.Refund_EPE_Only__c = date.today();
    }
    //Adv Refund
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund Advantage';
       a.Refund_Advantage__c = date.today();
    
   
    }
      //IPC Refund
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund IPC';
       a.Refund_IPC__c = date.today();
    }
   
    //Refund Momentum Support Standard
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'Refund' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Standard') {
       a.Account_Status__c = 'Refund Momentum';
       a.Refund_Momentum__c = date.today();
    }
     //Refund Momentum Support Plus
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'Refund' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus-Free')) {
       a.Account_Status__c = 'Refund Momentum Plus';
       a.Refund_Momentum_Plus__c= date.today();
    }

    }
       updatedAccSt.add(a);
       
}
if(updatedAccSt.size()>0)
{
update updatedAccSt;
}

}

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student


got the map working, except it fails to deploy or test due to

Too many SOQL: 101

This is weird as there is only one?

This is my code: Thank you in advance


trigger ClientPath_Transaction on Transaction__c (before insert) {
List<Account_Status__c> AccSt = new List<Account_Status__c>();
List<Account_Status__c> updatedAccSt = new List<Account_Status__c>();
List<Id> accIds = new List<Id>();
 set<Id> traserviceIDset = new set<Id>();
 for (Transaction__c Tra : Trigger.new)
         traserviceIDset.add(Tra.Destiny_Service_No__c);

map<id, service__c> servicesMap = new Map<id, Service__c>([Select id, Service_Name__c, service_type__c from Service__c where id in :traserviceIDset limit 1]);


for (Transaction__c Tra: Trigger.New) {
       if(Tra.Account__c != null && (Tra.Transaction_Type__c == 'First Payment'||Tra.Transaction_Type__c == 'Refund')) {
       
       
       accIds.add(Tra.Account__c);
       }
       }
  AccSt = [Select Id,Account_Status__c from Account_Status__c WHERE Account__c in :accIds];
  for(Account_Status__c a : AccSt)
  {
  

  
for (Transaction__c Tra: Trigger.New ) {
//First Payment Services
//EPE Only
if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Essential Property Education Only' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client' && Tra.Transaction_Type__c == 'First Payment') {
       a.Account_Status__c = 'EPE Course Only';
       a.EPE_Course_Only__c = date.today();
    }
    //Adv New Client
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client'&& Tra.Transaction_Type__c == 'First Payment') {
       a.Account_Status__c = 'EPE Course: Advantage';
       a.EPE_Course_Advantage__c = date.today();
    }
    //Adv Upgrade from EPE
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Adv Upgrade EPE 1x New'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Adv Upgrade EPE 2x New')) {
       a.Account_Status__c = 'Support: Advantage';

    }
      //IPC New Client
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'First Payment' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'New Client') {
       a.Account_Status__c = 'EPE Course: IPC';
       a.EPE_Course_IPC__c = date.today();
    }
    //IPC Upgrade from EPE
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'IPC Upgrade EPE 1x New'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'IPC Upgrade EPE 2x New')) {
       a.Account_Status__c = 'Support: IPC';
      
    }
    //Momentum Support Standard
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'First Payment' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Standard') {
       a.Account_Status__c = 'Support: Momentum';
       a.Support_Momentum__c = date.today();
    }
     //Momentum Support Plus
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'First Payment' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus-Free')) {
       a.Account_Status__c = 'Support: Momentum Plus';
       a.Support_Momentum_Plus__c = date.today();
    }
    
    
    
//Refund Services
//EPE Only Refund
if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Essential Property Education Only' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund EPE Only';
       a.Refund_EPE_Only__c = date.today();
    }
    //Adv Refund
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Advantage Program' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund Advantage';
       a.Refund_Advantage__c = date.today();
    
   
    }
      //IPC Refund
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Intensive Property Coaching' && Tra.Transaction_Type__c == 'Refund') {
       a.Account_Status__c = 'Refund IPC';
       a.Refund_IPC__c = date.today();
    }
   
    //Refund Momentum Support Standard
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'Refund' && servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Standard') {
       a.Account_Status__c = 'Refund Momentum';
       a.Refund_Momentum__c = date.today();
    }
     //Refund Momentum Support Plus
    if(servicesMap.get(Tra.Destiny_Service_No__c).Service_Name__c == 'Momentum Support' && Tra.Transaction_Type__c == 'Refund' && (servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus'||servicesMap.get(Tra.Destiny_Service_No__c).Service_Type__c == 'Plus-Free')) {
       a.Account_Status__c = 'Refund Momentum Plus';
       a.Refund_Momentum_Plus__c= date.today();
    }

    }
       updatedAccSt.add(a);
       
}
if(updatedAccSt.size()>0)
{
update updatedAccSt;
}

}


Eli Flores, SFDC DevEli Flores, SFDC Dev

Hi,

The code looks pretty good and as far as I can tell, you don't have any soql inside of loop which is generally the cause of this. though i have to confess your style is different than mine so it's a bit hard for me to follow your code. 

I'd check the debug logs. I'm willing to be that your update (Account_Status__c) is firing off triggers for Account_status__c which probably are then doing some sort of update and firing off this trigger again.

If that's the case, you may have to rethink your design. Maybe pulling all these triggers into one "transaction manager" class that handles all the related updates in one spot so you can stop a trigger loop. 


 

Developer.mikie.Apex.StudentDeveloper.mikie.Apex.Student
I am still new to code. I am getting better and better everyday, but I still cosnider myself a beginning. I have only just started understanding joining multiple triggers into one. Is there any way you could supply some example code on how I may 'pull all these triggers into one transaction manager class'.

Thank you for your continued correspondence!