• Oliver_Dunford
  • NEWBIE
  • 0 Points
  • Member since 2013

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 3
    Questions
  • 8
    Replies

I'm learning apex so have set myself some challenges and I'm trying to get some best practice help.  I have a trigger (important snippets below) which passes the inserted Slots__c record(s) into my class. That's all I want the trigger to do really as I understand that's the best way to do things.

 

trigger InsertAvailableServices on Slots__c (before insert, before update, after insert, after update) {
    if(trigger.isAfter){
        if(trigger.isInsert){
            OpeningInsertAfter myInsertAfter = new OpeningInsertAfter(Trigger.new);
        }
    }
}

In my class, I want to get the information from the inserted Slot__c record so that I can use this within another SOQL query against an un-related object.  I can get all this to work in a trigger but now it's time to learn about classes and doing things correctly.

 

1.  I'm sure there a better way to store the field values from the inserted Slot__c record, rather than having a load of public variables like my logic below? e.g. public string AccountId {get; set;}

 

//constructor accepting a list of myObjects
    public OpeningInsertAfter(Slots__c[] myOpenings){
		for (Slots__c opp:myOpenings){
			OpeningId = opp.Id;
			OpeningDuration = opp.Duration_mins__c;
			Discount = opp.Discount__c;
			AccountId = opp.Account__c;
			StartDate = opp.Start_Time__c;
		}	          
    }       

 2. My next challenge is constructing the rest of the class.  How do I call this method so that it exectutes? It's purpose is to build a list of available_treatment__c records.

 

    public OpeningInsertAfter() { 
		TheServices = [select Id, Name, Account__c, Duration_Int__c, Price__c 
		from Treatment__c where Account__c =: AccountId and Duration_Int__c <=: OpeningDuration];
    		System.Debug('Treatment List' + TheServices);
    		for (Treatment__c service : TheServices) {
	              {
	                   availableServices.add(new Available_Treatments__c
	                   (Slot__c = OpeningId, treatment__c = service.id, Start_Time__c = StartDate,
	                   Duration_mins__c = service.Duration_Int__c,
	                   Internet_Price__c = service.Price__c - ((service.Price__c * Discount) / 100),
	                   Treatments_for_Slot__c = ((OpeningDuration / service.Duration_Int__c).round(roundingMode.DOWN))));          
	               }
	         }
		Insert availableServices; 
    } 

A chopped down version of my current class is as follows:

 

public class OpeningInsertAfter {
//my public variables here
public List<Treatment__c> TheServices {get; set;}

 public OpeningInsertAfter() { 
   //this goes off and builds a list of records to insert into available_treatments__c object
//I use the details from the inserted Slots__c record here } public OpeningInsertAfter(Slots__c[] myOpenings){ for (Slots__c opp:myOpenings){ //grabs all the details from inserted record } }

 

Hi Everyone, 

 

I'm trying to learn APEX and wonder whether you could help.  I have a trigger which simply calls a class when a Slot__c record is inserted or updated.

 

trigger InsertAvailableServices on Slots__c (after insert, after update) {
    //Pass new/updated slot record to class    	
    AvailableServicesController.handleOpeningChange(Trigger.old, Trigger.new);    	
}

 My class is as follows and works until I add the following line and then it all goes rather wrong. 

 

insert availableTreatments; 

 

public class AvailableServicesController {
        public class AvailableServicesException extends Exception {}
        public static void handleOpeningChange(List<Slots__c> oldSlots, List<Slots__c> newSlots) { 

            for (Slots__c slot : newSlots) {  

            List<Treatment__c> treatments = [select Id, Name, Account__c, Duration_Int__c, Price__c from Treatment__c where Account__c =: slot.Account__c and Duration_Int__c <=: slot.Duration_mins__c];
            
            if (treatments.size() == 0) {  
                throw new AvailableServicesException('There are no Available Products/Services for your opening duration');  // then an exception is thrown.
            }
            
                List<Available_Treatments__c> availableTreatments = new List<Available_Treatments__c>();
	       	
	            for (Treatment__c treatment : treatments) {
	               if (treatment.Duration_Int__c <= slot.Duration_mins__c) {
	                   AvailableTreatments.add(new Available_Treatments__c(Slot__c = slot.id, treatment__c = treatment.id, Start_Time__c = slot.Start_Time__c,
	                                                                       Duration_mins__c = treatment.Duration_Int__c,
	                                                                       Internet_Price__c = treatment.Price__c - ((treatment.Price__c * slot.Discount__c) / 100),
	                                                                       Treatments_for_Slot__c = ((slot.Duration_mins__c / treatment.Duration_Int__c).round(roundingMode.DOWN))));          
	                }
	            }
	            
	            insert availableTreatments; 
            }

        }
    } 

I get this error: 

 

Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, InsertAvailableServices: maximum trigger depth exceeded
Slots trigger event AfterInsert for [a00i0000003ejIb]
Slots trigger event AfterUpdate for [a00i0000003ejIb]

 

I'm sure it's because I'm trying to do everything in for loops of death, but here are the things I can't quite work out. 

 

1.  When a Slots__c record is inserted I need to store information about it for use in SOQL queries e.g. AccountId and Duration_mins__c.  I had it working with a load of variables but it just feels messy.  Not sure what the best way to do this is?

 

2.  For each inserted Slots__c record I want to query a list of Treatment__c based on criteria from the Slot__c record.  I then want to insert these records into the Available_Treatments__c object.  I also need to populate this object with information from the inserted Slot__c record.

 

My challenge is that I always need to re-use information from the Slot__c record throughout my SOQL queries and when I'm populating the list for insert.  I could put everything in variables but is there a better way?

 

Thanks

 

Hi There, 

 

I'm new to APEX and I'm struggling to get some code working.  I wanted to make it nice and neat and do things right rather than swamping it all with for loops etc.  A single Slot__c record will be created and them I'm looking to insert a list of records into a child object (master detail).

 

My code below goes off and returns a list of Treatment__c records and inserts into a map.  All is well so far.  I am now struggling with the following:

 

1. The trigger fires after the creation of a Slot__c record.  For each inserted parent I would like to also insert the Slot__c.Id value into a variable within the Map so I can relate the child record to it's parent upon insertion.

 

2. My SOQL query WHERE clause has duration hard coded to <= '100'.  I would like to include the Slot__c.Duration field from the Parent Record here instead.

 

3. I then want to take my map and insert all these records into an object Available_Treatments__c.  I'm struggling to do this as well.

 

I'm pretty new to all this, so help would be appreciated.  I may well be over complicating it.

 

trigger InsertAvailableTreatments on Slots__c (after insert) {

 

Map<id,List<Treatment__c>> mapTreatmentObj = new Map<id,List<Treatment__c>>();
for(Treatment__c tr : [SELECT Id, Name, Account__c, Duration__c FROM Treatment__c WHERE Duration__c <= '100']) {
List<Treatment__c> treatmentsForKey = mapTreatmentObj.get(tr.Id);
if (treatmentsForKey == null) {
treatmentsForKey = new List<Treatment__c>();
mapTreatmentObj.put(tr.Id, treatmentsForKey);
}
treatmentsForKey.add(new Treatment__c( Id = tr.Id, Name = tr.Name, Duration__c = tr.Duration__c, Account__c = tr.Account__c ));
System.Debug('Name' + tr.Name);
}

}

 

I was thinking about how to create a trigger that reads through all campaign members of a certain campaign and updates a custom campaign text field with a string containing the names of all members.

 

For example, in campaign "A" there are 3 members whose names are "John", "Joe" and "Jack". A custom field Member_List__c on "A" would read (after the trigger is executed) "John, Joe, Jack". (In my case, campaigns have only a small number of members so a default text field is fine, no need for long text areas)

 

Do you have any ideas?

 

Thank you!! 

  • July 11, 2013
  • Like
  • 0

I'm learning apex so have set myself some challenges and I'm trying to get some best practice help.  I have a trigger (important snippets below) which passes the inserted Slots__c record(s) into my class. That's all I want the trigger to do really as I understand that's the best way to do things.

 

trigger InsertAvailableServices on Slots__c (before insert, before update, after insert, after update) {
    if(trigger.isAfter){
        if(trigger.isInsert){
            OpeningInsertAfter myInsertAfter = new OpeningInsertAfter(Trigger.new);
        }
    }
}

In my class, I want to get the information from the inserted Slot__c record so that I can use this within another SOQL query against an un-related object.  I can get all this to work in a trigger but now it's time to learn about classes and doing things correctly.

 

1.  I'm sure there a better way to store the field values from the inserted Slot__c record, rather than having a load of public variables like my logic below? e.g. public string AccountId {get; set;}

 

//constructor accepting a list of myObjects
    public OpeningInsertAfter(Slots__c[] myOpenings){
		for (Slots__c opp:myOpenings){
			OpeningId = opp.Id;
			OpeningDuration = opp.Duration_mins__c;
			Discount = opp.Discount__c;
			AccountId = opp.Account__c;
			StartDate = opp.Start_Time__c;
		}	          
    }       

 2. My next challenge is constructing the rest of the class.  How do I call this method so that it exectutes? It's purpose is to build a list of available_treatment__c records.

 

    public OpeningInsertAfter() { 
		TheServices = [select Id, Name, Account__c, Duration_Int__c, Price__c 
		from Treatment__c where Account__c =: AccountId and Duration_Int__c <=: OpeningDuration];
    		System.Debug('Treatment List' + TheServices);
    		for (Treatment__c service : TheServices) {
	              {
	                   availableServices.add(new Available_Treatments__c
	                   (Slot__c = OpeningId, treatment__c = service.id, Start_Time__c = StartDate,
	                   Duration_mins__c = service.Duration_Int__c,
	                   Internet_Price__c = service.Price__c - ((service.Price__c * Discount) / 100),
	                   Treatments_for_Slot__c = ((OpeningDuration / service.Duration_Int__c).round(roundingMode.DOWN))));          
	               }
	         }
		Insert availableServices; 
    } 

A chopped down version of my current class is as follows:

 

public class OpeningInsertAfter {
//my public variables here
public List<Treatment__c> TheServices {get; set;}

 public OpeningInsertAfter() { 
   //this goes off and builds a list of records to insert into available_treatments__c object
//I use the details from the inserted Slots__c record here } public OpeningInsertAfter(Slots__c[] myOpenings){ for (Slots__c opp:myOpenings){ //grabs all the details from inserted record } }

 

Hi Everyone, 

 

I'm trying to learn APEX and wonder whether you could help.  I have a trigger which simply calls a class when a Slot__c record is inserted or updated.

 

trigger InsertAvailableServices on Slots__c (after insert, after update) {
    //Pass new/updated slot record to class    	
    AvailableServicesController.handleOpeningChange(Trigger.old, Trigger.new);    	
}

 My class is as follows and works until I add the following line and then it all goes rather wrong. 

 

insert availableTreatments; 

 

public class AvailableServicesController {
        public class AvailableServicesException extends Exception {}
        public static void handleOpeningChange(List<Slots__c> oldSlots, List<Slots__c> newSlots) { 

            for (Slots__c slot : newSlots) {  

            List<Treatment__c> treatments = [select Id, Name, Account__c, Duration_Int__c, Price__c from Treatment__c where Account__c =: slot.Account__c and Duration_Int__c <=: slot.Duration_mins__c];
            
            if (treatments.size() == 0) {  
                throw new AvailableServicesException('There are no Available Products/Services for your opening duration');  // then an exception is thrown.
            }
            
                List<Available_Treatments__c> availableTreatments = new List<Available_Treatments__c>();
	       	
	            for (Treatment__c treatment : treatments) {
	               if (treatment.Duration_Int__c <= slot.Duration_mins__c) {
	                   AvailableTreatments.add(new Available_Treatments__c(Slot__c = slot.id, treatment__c = treatment.id, Start_Time__c = slot.Start_Time__c,
	                                                                       Duration_mins__c = treatment.Duration_Int__c,
	                                                                       Internet_Price__c = treatment.Price__c - ((treatment.Price__c * slot.Discount__c) / 100),
	                                                                       Treatments_for_Slot__c = ((slot.Duration_mins__c / treatment.Duration_Int__c).round(roundingMode.DOWN))));          
	                }
	            }
	            
	            insert availableTreatments; 
            }

        }
    } 

I get this error: 

 

Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, InsertAvailableServices: maximum trigger depth exceeded
Slots trigger event AfterInsert for [a00i0000003ejIb]
Slots trigger event AfterUpdate for [a00i0000003ejIb]

 

I'm sure it's because I'm trying to do everything in for loops of death, but here are the things I can't quite work out. 

 

1.  When a Slots__c record is inserted I need to store information about it for use in SOQL queries e.g. AccountId and Duration_mins__c.  I had it working with a load of variables but it just feels messy.  Not sure what the best way to do this is?

 

2.  For each inserted Slots__c record I want to query a list of Treatment__c based on criteria from the Slot__c record.  I then want to insert these records into the Available_Treatments__c object.  I also need to populate this object with information from the inserted Slot__c record.

 

My challenge is that I always need to re-use information from the Slot__c record throughout my SOQL queries and when I'm populating the list for insert.  I could put everything in variables but is there a better way?

 

Thanks

 

Hi There, 

 

I'm new to APEX and I'm struggling to get some code working.  I wanted to make it nice and neat and do things right rather than swamping it all with for loops etc.  A single Slot__c record will be created and them I'm looking to insert a list of records into a child object (master detail).

 

My code below goes off and returns a list of Treatment__c records and inserts into a map.  All is well so far.  I am now struggling with the following:

 

1. The trigger fires after the creation of a Slot__c record.  For each inserted parent I would like to also insert the Slot__c.Id value into a variable within the Map so I can relate the child record to it's parent upon insertion.

 

2. My SOQL query WHERE clause has duration hard coded to <= '100'.  I would like to include the Slot__c.Duration field from the Parent Record here instead.

 

3. I then want to take my map and insert all these records into an object Available_Treatments__c.  I'm struggling to do this as well.

 

I'm pretty new to all this, so help would be appreciated.  I may well be over complicating it.

 

trigger InsertAvailableTreatments on Slots__c (after insert) {

 

Map<id,List<Treatment__c>> mapTreatmentObj = new Map<id,List<Treatment__c>>();
for(Treatment__c tr : [SELECT Id, Name, Account__c, Duration__c FROM Treatment__c WHERE Duration__c <= '100']) {
List<Treatment__c> treatmentsForKey = mapTreatmentObj.get(tr.Id);
if (treatmentsForKey == null) {
treatmentsForKey = new List<Treatment__c>();
mapTreatmentObj.put(tr.Id, treatmentsForKey);
}
treatmentsForKey.add(new Treatment__c( Id = tr.Id, Name = tr.Name, Duration__c = tr.Duration__c, Account__c = tr.Account__c ));
System.Debug('Name' + tr.Name);
}

}