Take the 2-minute tour ×
Salesforce Stack Exchange is a question and answer site for Salesforce administrators, implementation experts, developers and anybody in-between. It's 100% free, no registration required.

I'm writing a trigger to create a new Event on update of Opportunity. There are some required fields and others are optional in the form that the user submits. I'm trying to determine a good way to filter for fields that don't contain any data when creating the new events. The trigger operates on a check box custom Opportunity object field that gets set when the opportunity is submitted/updated which tells the trigger to create the event.

If possible, I'd prefer not to have a series of nested if statements to test each field for data. Only about 40% of the possible fields are required or locked into the form the user submits.

trigger ScheduleAmbassadorEvent on Opportunity (after update) {

/* Get Opp IDs being processed by trigger where box is checked for opps After Update */

Integer s = [SELECT Count() FROM Opportunity WHERE Id IN :Trigger.new AND Opportunity.Schedule_Ambassador__c = true];

   If (s != 0) {

list <opportunity> NwEvnt = [SELECT Id, Name, Description, CloseDate, LeadSource, CreatedDate, Account_Address__c, Recap_Type__c, Event_Start_Time__c, Event_Info__c, Schedule_Ambassador__c, Planned_Mintues__c, ECAL_c__c, Campaign.Name, Owner.Name, Program_PO__r.Name, SWS_Recomended_CE__r.Name, SWS_Recomended_CE__r.Phone, SWS_Recomended_CE__r.Email, Customer_Contact__r.Name, Customer_Contact__r.Phone, Customer_Contact__r.Email FROM Opportunity WHERE Id IN :Trigger.new AND Schedule_Ambassador__c = true]; 

From here, I can either create a huge multitude of maps, or I can begin building the list of Events using the required information, then later add the optional information. Once I'm done, I'll be resetting the Schedule_Ambassor__c field to false so it won't trip the trigger again unless a another opportunity on the acct requires a new event to be created.

I've seen the following code which I'll admit I don't fully understand. Consequently I've wondered how I could apply it to what I have above.

String queryString = 'SELECT Id, Name, ' + 
       '(SELECT FirstName, LastName FROM Contacts LIMIT 1) FROM Account';
SObject[] queryParentObject = Database.query(queryString);

for (SObject parentRecord : queryParentObject){ 
Object ParentFieldValue = parentRecord.get('Name'); 
// Prevent a null relationship from being accessed
SObject[] childRecordsFromParent = parentRecord.getSObjects('Contacts');
if (childRecordsFromParent != null) {
    for (SObject childRecord : childRecordsFromParent){ 
        Object ChildFieldValue1 = childRecord.get('FirstName'); 
        Object ChildFieldValue2 = childRecord.get('LastName'); 
        System.debug('Account Name: ' + ParentFieldValue + 
        '. Contact Name: '+ ChildFieldValue1 + ' ' + ChildFieldValue2);
    }
  }              
}

I'm not accessing a record from a parent, thus part of why it confuses me. I am however accessing related lists. Regardless, it seems that the same concept should work to determine whether or not a record is null. If it's not then add it to the list. Once an Event record was populated, I presume I could then insert it and later do a query to run a system assert for validation that each one was properly inserted into the database; something I've never had to do before in a trigger. I've seen code that would look like this:

Event[] event = new Event[]{};

for (list<Opportunity> e : NwEvnt) {
Event event = new Event(Owner = 'e.Owner.Name' + ',' + 'e.ECAL_c__c'), Start = e.Event_Start_Time__c,  ActivityDate = e.CloseDate, Description = e.Description, DurationInMinutes = e.Planned_Minutes__c, Location = e.Event_Info__c, Who = e.Customer_Contact__c, Phone = e.Customer_Contact__r.Phone, Start = e.Event_Start_Time__c, IsVisibleInSelfService = true, CreatedBy = e.Owner.Name, Subject='EventAssignment');

/* my thought was to add the required fields first, and then use If statements to add the optional fields to each new event once I determined whether or not it was null if I couldn't come up with some kind of SObject describe method to determine whether or not a field was null. If I could, it would be inserted here before continuing. */

Event.add(event);
}

try {
    insert Event;
    } catch (DmlException e) {
    System.debug(e.getMessage());
}

Am I on the right track with this final part? Any suggestions for improvement would be appreciated. Thanks!

share|improve this question
    
Why do you need to check if the fields are null? I assume those opportunity fields are just being mapped to the event but if they are null won't the event just have a null value in the field. I.E. where is the nullpointer exception coming from? –  Greg Grinberg Jan 16 '13 at 19:19
    
I think you are on the right track with respect to using if statements for optional fields. Couldn't figure what did you want from the "sample" code though :) –  Sai Jan 16 '13 at 19:22
add comment

1 Answer 1

up vote 0 down vote accepted

There are a couple of other issues with your trigger. If all you want to do is create an event based on the opportunity fields when this box is checked then the following should work.

trigger ScheduleAmbassadorEvent on Opportunity (after update)
{
    //Note: You don't need to do any soql queries since trigger.new already has the opportunities.
    list<Opportunity> NwEvnt = new list<Opportunity>();
    for(Opportunity opp: trigger.new) 
    {
        if(opp.Schedule_Ambassador__c) nwEvnt.add(opp);
    }

    list<Event> ToInsert = new list<Event>();
    for(Opportunity opp : newEvnt)
    {
        Event e = New Event(//was this meant to be Name? Ownerid is a lookup field to user so it wouldn't normally have text in there.
                            //Owner = opp.Owner.Name + ',' + opp.ECAL_c__c, 
                            Start = opp.Event_Start_Time__c,  
                            ActivityDate = opp.CloseDate, 
                            Description = opp.Description, 
                            DurationInMinutes = opp.Planned_Minutes__c, 
                            Location = opp.Event_Info__c, 
                            Who = opp.Customer_Contact__c, 
                            Phone = opp.Customer_Contact__r.Phone, 
                            Start = opp.Event_Start_Time__c, 
                            IsVisibleInSelfService = true, 
                            //I think you want to set ownerID as createdBy is a system field and cannot normally be set.
                            //CreatedBy = opp.Owner.Name, 
                            OwnerID = opp.OwnerID,
                            Subject='EventAssignment')
        ToInsert.add(e);
    }

    if(ToInsert.IsEmpty() == false)
    {
        /**using database.insert allows you to do a partial success so if some of the events fail because of missing required fields or something else it will still go through (assuming this is what you want). You can then handle the errors in the saveresult any way you want, debugging them to the log, sending yourself an email, etc.
        **/
        list<Database.SaveResult> InsertResults = Database.Insert(ToInsert,false);
    }
}
share|improve this answer
    
I'm not getting a null exception (yet), but know it often happens when accessing fields with null data, so was trying to prevent it from happening. By def, in this org, Event.Owner = (User, ECAL_c__c). Should I use the ID or the Opp Owner's Name (also the Event Owner)? Have assumed they want to see the name. Since trigger is creating the Event, don't I need to set CreatedBy to the owner of the Event? This is where my lack of experience with this kind of programming really shows. Glad to know the database insert allows partial success! Learn something new every day. :) –  crmprogdev Jan 16 '13 at 20:20
    
You'll only get a null exception if you try and do null.somemethod. So if the opportunity was null you would get a null pointer exception but not if it was just one of the fields. Event.Owner is a lookup so it is always populated with the ID (foreign key) even though it shows a name. CreatedBy is filled in automatically with the running user (whoever kicked off the trigger). –  Greg Grinberg Jan 16 '13 at 22:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.