• Todd B.
  • NEWBIE
  • 85 Points
  • Member since 2012
  • Director, Sales Operations
  • Magellan Health Services


  • Chatter
    Feed
  • 0
    Best Answers
  • 2
    Likes Received
  • 1
    Likes Given
  • 22
    Questions
  • 21
    Replies
I have written a basic VF page to view and add phone numbers to a custom object.  The page and the controller work, but I can not figure out the test class.  I am receiving an error message that I am missing a required field.

VF Page:
<apex:page standardController="Task"  extensions="CurrentPhoneRecords_controller" sidebar="false" showHeader="false">
<apex:form >

    <apex:pageBlock >
        <apex:pageBlockSection id="MemberSummary" title="Member Summary" showheader="true" columns="2">
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.First_Name__c}"/>
            <apex:outputField Label="Age" value="{!Task.SD_Member_Stakeholders__r.Age_SD_Member__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Last_Name__c}"/>
            <apex:outputField Label="DOB" value="{!Task.SD_Member_Stakeholders__r.Date_of_Birth__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_Address__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Phone_Last_Research_Date__c}"/>   
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_City__c}"/>
            <apex:outputField Label="Click to View Member Record" value="{!Task.WhatId}"/>       
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_State__c}"/>    
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Intelius_Search_Link__c}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
  

<!-- Add a New Phone Number-->
    <apex:actionregion >
        <apex:outputPanel id="AddPhoneNumber" >
            <apex:pageBlock title="Add a New Phone Number" rendered="True">
                <apex:pageBlockButtons location="top" >    <!-- component to contain all the buttons, can show buttons on top, bottom of the record or both -->
                    <apex:commandButton value="New" action="{!newPH}" reRender="AddPhoneNumber" rendered="{!!editPH}"  >
                        <apex:param name="editPH" value="true" assignTo="{!editPH}"/>
                    </apex:commandButton>
                    <apex:commandButton value="Save" action="{!savePH}"  rerender="AddPhoneNumber, PhoneList" rendered="{!editPH}">
                        <apex:param name="SavePH" value="False" assignTo="{!editPH}"/>
                    </apex:commandButton>                    
                    <apex:commandButton value="Save & New" action="{!savenewPH}"  rerender="AddPhoneNumber, PhoneList" rendered="{!editPH}">
                        <apex:param name="SavePH" value="True" assignTo="{!editPH}"/>
                    </apex:commandButton>
<!-- The Cancel Button is not working yet
                    <apex:commandButton value="Cancel" immediate="true" rerender="AddPhoneNumber" rendered="{!editPH}" >
                        <apex:param name="cancelPH" value="false" assignTo="{!editTask}"/>
                    </apex:commandButton>                    
-->
                </apex:pageBlockButtons>
        <apex:pageBlockSection columns="2" >
<!-- View only Fields
           <apex:outputField value="{!ph.Phone_Number__c}" rendered="{!!editPH}" />
           <apex:outputField value="{!ph.Phone_Number_Status__c}" rendered="{!!editPH}" />
           <apex:outputField value="{!ph.Phone_Type__c}" rendered="{!!editPH}" />
-->           
<!-- Add New Phone Number Fields-->
           <apex:inputField value="{!ph.Phone_Number__c}" rendered="{!editPH}" />
           <apex:inputField value="{!ph.Phone_Number_Status__c}" rendered="{!editPH}" />
           <apex:inputField value="{!ph.Phone_Type__c}" rendered="{!editPH}" /> 
         </apex:pageBlockSection>
            </apex:pageBlock>
        </apex:outputPanel>
    </apex:actionregion>

<apex:actionRegion >
    <apex:pageBlock >
        <apex:pageBlockSection id="PhoneList" title="Current Phone Numbers" showHeader="true" columns="1" onclick="saveState(this);">
            <apex:pageBlockTable value="{!PhoneRecords}" var="i" width="100%" border="1" cellspacing="2" cellpadding="2"  >
                <apex:column value="{!i.Phone_Number__c}"/> 
                <apex:column value="{!i.Phone_Number_Status__c}"/> 
                <apex:column value="{!i.Phone_Type__c}"/> 
            </apex:pageBlockTable>
       </apex:pageBlockSection>
    </apex:pageBlock> 
</apex:actionRegion>    

</apex:form>                                        
</apex:page>



Controller:
/*
  Class        : CurrentPhoneRecords
  Developer    : Todd Barry
  Created      : June 1, 2018
  Objective    : Controller for PRM vsiualforce page. 
  Updates      :              
*/

 public class CurrentPhoneRecords_controller {

    Private Task T1;
    Public Phone_Numbers__c PhoneRecords;
    Public boolean editPR {get;set;}                //store boolean variable for making fields editable

    public string sObjectName02 = 'Phone_Numbers__c';//string specifying object name for use in dynamic query
    public string sObjectFields02 {get;set;}         //string that will hold csv of all fields on SDMember
    public string sObjectID02 {get;set;}             //parameter which will be assigned from visualforce page and used to query SDMember with the given ID
    public string sObjectSOQL02 {get;set;}           //string of the complete SOQL query that returns all fields on SDMember
    public string strSDMemberID {get;set;}    
    
    
    public Phone_Numbers__c PH {get;set;}
    public id PHID {get;set;}                        //Phone Number id from SOQL query
    public boolean editPH {get;set;}
    
    public CurrentPhoneRecords_Controller(ApexPages.StandardController controller) {
        this.t1= (Task)Controller.getRecord();        
}
    
                
    
     Public List <Phone_Numbers__c> getPhoneRecords() {
     
        Task t2 = [Select id, whatid from Task where id = :t1.id];  
        strSDMemberID = t2.whatid;       
    
        List <Phone_Numbers__c> PhoneRecords = [Select Id,
                                                Phone_Number__c,
                                                Phone_Number_Status__c,
                                                Phone_Type__c,
                                                Override_Request_Status__c,
                                                SD_Member_Link__c 
                                                From Phone_Numbers__c 
                                                Where SD_Member_Link__c = :t2.whatid];
        return PhoneRecords;                                        
    
    }
    
   Public Void SavePhoneRecords() {
        if(PhoneRecords.id == Null)
            insert PhoneRecords;
        Else
            update Phonerecords; 
    }      
// Adding a new phone number
 public void getPH(){      // retrieve selected task
      
        sObjectFields02 = '';                          //initialize as an emply string to prevent 'null field__c, ...'
        //get the object then get the fields and then field names (returns a list and itterates through it)
        for(string field : schema.getglobaldescribe().get(sObjectName02).getdescribe().fields.getmap().keyset()){
           sObjectFields02 += field + ', ';           //build string of all fields on the given sObject
        }
        sObjectFields02 = sObjectFields02.substring(0,sObjectFields02.length()-2);    //remove the trailing comma
        sObjectFields02+=', lastmodifiedby.name';

        sObjectSOQL02 = 'select ' + sObjectFields02 + ' from ' + sObjectName02 + ' where id = \'' + sObjectId02 +'\'';    //build complete query statement for SDMember which includes all the fields for easy reference
        System.debug (sObjectSOQL02);
        PH = Database.query(sObjectSOQL02);             
 
    }
    
    Public void newPH(){
    PH = New Phone_Numbers__c();
    ph.Phone_Number_Status__c ='Not Called Yet';
    Ph.Phone_Type__c = 'Intelius';
    ph.SD_Member_Link__c = strSDMemberID;

    
    }
    
    public void savePH(){
        if(ph.id == null)         // if new task then insert
            insert PH;
        else
            update PH;            // otherwise update task
    }        
    
        public void savenewPH(){
        if(ph.id == null)         // if new task then insert
            insert PH;
            // Create New PH entry
            PH = New Phone_Numbers__c();
            ph.Phone_Number_Status__c ='Not Called Yet';
            Ph.Phone_Type__c = 'Intelius';
            ph.SD_Member_Link__c = strSDMemberID;
    
    }
         
}

 Test Class:
@isTest
public class TestClass_Outreach_Console_Controller {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test

date dtTestDate  = System.today() + 5;

        // Create User Record 
User u1 = [SELECT Id FROM User Where isActive=True  LIMIT 1];

//Create Service Center
Service_Center__c SC = new Service_Center__c(Name='Test1');
Insert sc;


// Create SD Member Record
SD_Member__c sd = New SD_Member__c(First_Name__c = 'John', 
                                   Last_Name__c = 'Smith', 
                                   Ins_ID_Member__c = '123456', 
                                   Ins_ID_Suscriber__c = '456789',
                                   address__c = '123 Main Street', 
                                   city__c = 'Aster', 
                                   state__c = 'CT', 
                                   zip__c = '06001', 
                                   name = 'John Smith',
                                   Lost_Contact_Follow_Up__c = False,
                                   Mailing_Cycle__c='Week 2.1',
                                   Total_Opt_out__c = False,
                                   Catasys_Stops_Phone_Follow_Ups__c=False,
                                   P10M_Impactable_Cost__c=500,
                                   Work_Phone__c='8607985214',
                                   Member_Eligibility_Status__c='Eligible',
                                   Service_Center__c=sc.id,
                                   Referral_Source__c='Claims Data',
                                   Catasys_Medical_Exclusion_Status__C='Medically Targeted',
                                   Enrollment_Progress_Status__c='Attempting to Contact',
                                   Post_Referral_to_CC_Status__c='Pre Referral',
                                   Carecoach__c = u1.id);
insert sd;

// Create New Phone Record
Phone_Numbers__c phTest = New Phone_Numbers__c(SD_Member_Link__c = sd.id,
                                           Phone_Number__c = '8951239874',
                                           Phone_Type__c = 'Home',
                                           Phone_Number_Status__c = 'Not Called Yet');
insert phTest;        
                                           
        

Task t11 = new Task();
t11.WhatId=sd.id;
t11.Subject = '[Phone Number Research]'; //set the required fields
t11.Status ='In Progress';
t11.ActivityDate = dtTestDate;        
Insert t11;        

Id taskID;
taskID = t11.Id;


 
// Test the currentPhoneRecords_Controller
	ApexPages.StandardController stdController = new ApexPages.StandardController(t11);
        CurrentPhoneRecords_controller cpr = new CurrentPhoneRecords_controller(stdController);
        
        cpr.getPhoneRecords();
        
        cpr.newPH();
        
        cpr.ph.Phone_Number__c = '1234567890';
        
        cpr.savenewPH();
        cpr.savePH();
        
      
    }
}

The issue i am having is with this line:  cpr.ph.Phone_Number__c = '1234567890';.  I am trying to input a new phone number to test the savenewPH and save PH methods.  The error I am receving is System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Phone_Number__c]: [Phone_Number__c] 

How do I set the value of an inputfield in the VF page? 
 
I have been handed a fairly complex VF page to update.  The are several sections on the page, call updated by clicking on a row in a table.  The issue I am having is, when some updates one of the subsections on the page, I need the entire page to refresh.  Currently, I have a two button process, the first button is the standard "Save" functionality:
<apex:commandButton value="Save" action="{!saveTask}" status="loadSDMember" oncomplete="RefreshText();" rerender="taskDetail, SDMember,  SDMemberSummary, PhoneDetail,  debug" rendered="{!editTask}">

<apex:param name="editTask" value="false" assignTo="{!editTask}"/>
                                        
</apex:commandButton>
Then I created a second button to refresh the page
<apex:commandButton value="Press Here After Saving" action="{!getSDMember}" status="loadSDMember" oncomplete="RefreshText();" rerender="taskDetail, SDMember,  SDMemberSummary, PhoneDetail,  debug">
                                       
<apex:param name="taskID" value="{!task.id}" assignto="{!taskID}" />                                        <apex:param name="editMode" value="false" assignto="{!editMode}" />                                        <apex:param name="editTask" value="false" assignto="{!editTask}" />                                        <apex:param name="viewFullRecord" value="false" assignto="{!viewFullRecord}" />                            <apex:param name="SDMemberID" value="{!SDMember.id}" assignto="{!sObjectID}" />
<apex:param name="PHID" Value="" assignTo="{!sObjectid02}" />

</apex:commandButton>

Is it possible to combined this into just one button?
I am trying to create a Chatter post from a visual workflow.  When an Oppty is won, I want to create a Chatter post congratulating the Oppty owner and have it come from their Manager.  So far I can I can do all that using the Create Record Action
User-added image

The issue I am running into, I want to @mention the Manager (so they know they "sent" a chatter post) so I created a text body formula:
User-added image 
but the Chatter post is listing the id, and not doing a true @mention
User-added image

Any ideas on how to do a proper @mention via a formula?

Thanks, 

Todd B. 
 
I created a simple visualforce page and inserted it into in a custom account page layout.
<apex:page standardController="Account" >
<body>
<table width="100%" border="0" cellspacing="5" cellpadding="5">
  <tbody>
    <tr>
      <td align="center">
         
                  <iframe frameborder="0" height="100" marginheight="0" marginwidth="0" align="center"            
                        src="https://www.google.com/uds/modules/elements/newsshow/iframe.html?q=%22{!Account.name}%22{!Account.Acronym__c}%22&amp;#38;rsz=small&amp;#38;format=728x180" width="728">
              </iframe>
            
    </td>
    </tr>
    <tr>
      <td>
      <table width="100%" border="0" cellspacing="5" cellpadding="5">
  <tbody>
    <tr>
      <td width="16%" align="center" valign="middle"  scope="col">&nbsp;</td>
      <td width="16%" align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="col"><p>Magellan</p></td>
      <td width="16%" align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="col">BH</td>
      <td width="16%" align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="col">NIA </td>
      <td width="16%" align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="col">RX</td>
      <td width="16%" align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="col">Employer</td>
    </tr>
    <tr>
      <td align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="row">Customer</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.var_Magellan_Customer__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.var_Customer_BH__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.var_Customer_NIA__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD">&nbsp;</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.var_Customer_Emp__c}" /></td>
    </tr>
    <tr>
      <td align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="row">Original Effective Date</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_OED_Mag__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_OED_BH__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_OED_NIA__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD">&nbsp;</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_OED_EMP__c}" /></td>

    </tr>
    <tr>
      <td align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="row">Current Effective Date</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CED_Mag__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CED_BH__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CED_NIA__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD">&nbsp;</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CED_Emp__c}" /></td>
    </tr>
    <tr>
      <td align="center" valign="middle" bgcolor="#0077C8" style="color: #FFFFFF" scope="row">Current Contract End date</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CCED_Mag__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CCED_BH__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CCED_NIA__c}" /></td>
      <td align="center" valign="middle" bgcolor="#DDDDDD">&nbsp;</td>
      <td align="center" valign="middle" bgcolor="#DDDDDD"><apex:outputField value="{!Account.rs_CCED_Emp__c}" /></td>
    </tr>
  </tbody>
</table>
      </td>
    </tr>
  </tbody>
</table>
<p>
<em>&nbsp;* The above information is based on the infomation provided below in the Magellan Contracts section. This data is still in the early stages of data collection.</em>
</p>
<hr/>
</body>
</apex:page>

I then enabled the visualforce page for all profiles and assigned all profiles the account page layout.  All profiles see the visualforce page when they click on an account, but only system admins get results for the iframe component:
<iframe frameborder="0" height="100" marginheight="0" marginwidth="0" align="center"            
                        src="https://www.google.com/uds/modules/elements/newsshow/iframe.html?q=%22{!Account.name}%22{!Account.Acronym__c}%22&amp;#38;rsz=small&amp;#38;format=728x180" width="728">
              </iframe>

If there something I need to enable on all the other profiles to allow them to see the Google News iframe?

Thanks,
Todd B.

 
I have two custom objects: 
  • printsf__Collateral_Send_History__c
  • SD_Member__c
The two objects are linked by a lookup field however, on the printsf__Collateral_Send_History__c a back end system populates a text field with SD_Member__c id.  So I created a trigger to take the field value and query the SD_member__c object and return the correct SD_member__c.name field to poplate the lookup field.  
 
trigger CreateSDMemberLinkage on printsf__Collateral_Send_History__c (Before Insert) {

    List<SD_Member__c > recordsToUpdate = new List<SD_Member__c >();
    
    For(printsf__Collateral_Send_History__c CSH: Trigger.new) {
        String strId = csh.printsf__Recipient_ID__c;
        String StrId2 = csh.Name;
        String strId3 ;
    
    // Check to see if it is an SD Member Entry        
    If(CSH.printsf__Recipient_ID__c!=null){  

    
	// If this is a SD Member record, then query the SD Member object with the text based id
	// to get the matching SD Member name field to populate in the lookup field 
    For(SD_Member__c sd001 :  [Select Id, Name from SD_Member__C where id =: strid]){
    
	System.debug('SD Id:  '+ strid);

    strid3 = sd001.id;
    } 
    }
	
     csh.SD_Member_Stakeholders__c = strid3;

Everything is working as expected, but occasionally I receive an error:

Apex script unhandled trigger exception by user/organization: 0055000000118E4/00D50000000784t
CreateSDMemberLinkage: System.LimitException: Too many SOQL queries: 101


Any suggestions are to how I can clean up my code?

Thanks,
Todd B.
 
I created a Custom Object called SD_Member__c and on that object is a field Enrollment_Progress_Status__c which gets updated based on the result of a corresponding  Task.  I thought I did everything right, but periodically, I am getting a System.LimitException: Too many DML statements error.  Any ideas where my code may be causing this issue?
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

Map<id,Task> TaskMap = new Map<id,Task>([select id,RecordType.Name from Task 
                                         where id in : Trigger.newmap.keyset()]);
// Find qualifying tasks
for(Task record:Trigger.new)
        if(TaskMap.get(Record.id).RecordType.Name =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);
    update SD1; 
    
    }  }
Thanks, 

Todd B.
Since you can not use workflows to send an email update on a Event, I am working on creating a trigger that will send email.  I created an email template called MCC_Close_Event_Email and based it on the Event object.  I tested it and made sure it pulls all the correct info when sending.  

Then I created the trigger below to send the email when a cretain field is checked.  
trigger EventSendEmailMCCReminder on Event (After Update, After Insert) {

/*  Event e1 = trigger.new[0];  */
    For (Event e1 : trigger.New){
  String[] toAddresses = new String[] {e1.owner.email};
  String[] strProfile = New String[] {e1.owner.profile.name};    
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

  mail.setTargetObjectId(e1.OwnerID);
  mail.setSenderDisplayName('Salesforce Admin');
  mail.setUseSignature(false);
  mail.setBccSender(false);
  mail.setSaveAsActivity(false);  
  
  System.debug('Profile Name ' + e1.owner.profile.name);
  System.debug('Owner Name ' + e1.owner.name);  
  System.debug('Profile Name ' + strProfile);
  System.debug('To Address ' + toAddresses);        
    
	If(e1.SendMCCRemiderEmail__c == True ){
 /*       If(e1.owner.profile.name == 'System Administrator'){ */
		EmailTemplate et=[Select id from EmailTemplate where DeveloperName=:'MCC_Close_Event_Email'];
        mail.setTemplateId(et.id);
        Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});         
    }   
    }  
}
My issue is, it send the email, but all the Event related fields in the email are blank.  Also, all me System.Debug values are blank in the debug log.  

Any ideas to ensure the Event related fields in the Email are populated?
 
Hello All, 

I am new to writing Apex code and was able to wrtite the following piece to calculate both Divisional and Individual Sales goals.
 
public with sharing class FinancialPlanningTriggerHandle {
/* 
  Developer     : Todd Barry
  Created       : 05/27/2014
  Last Modified : 
  Test Class    : 
  Objective     : 
  
*/      
    public void beforeUpdate(Financial_Planning__c[] newlist){
        List<Date> dtStart =  new List<Date>();
        List<Date> dtEnd =  new List<Date>();
        List<String> strKey =  new List<String>();
        String strGT ;
        Double fpAmount = 0 ;
        String strname;
        
            for(Financial_Planning__c fp : newList){
              StrGT = fp.GoalType__c;
              dtStart.add(fp.period_start_date__c); 
              dtEnd.add(fp.period_End_date__c);
              strKey.add(fp.rptKey__c); 
              strname = fp.period_start_date__c.year() +' - ' +fp.division__c + ' - (' + fp.Revenue_Type__c + ')';
            }
                System.debug(strKey);
                System.debug(dtStart);
                System.debug(dtEnd);
                System.debug(strName);
                
        //Determine Which Recordtype you are working with
        if(strGT == 'Divisional Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }
        if(strGT == 'Personal Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }        
        
        
        
        
        }
    }

What I can not figure out is how to streamline some of the code.  I want to take this section and combined it into one IF statement:
//Determine Which Recordtype you are working with
        if(strGT == 'Divisional Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }
        if(strGT == 'Personal Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }

Basically, I want something like this:  

  if(strGT == 'Divisional Goal'){
      String A = select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
Else string A = select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
             
Then 

List<aggregateResult> fpresults = String A

But I am not sure how to do it.  Any ideas?

Regards, 

Todd B.
Hello All, 

I am trying to write a trigger for a certain Task record type
 
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

// Find qualifying tasks
for(Task record:Trigger.new)
     if(Record.RecordType.DeveloperName =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);
    update SD1; 
    
    }  }

But it keeps ignoring the line 
if(Record.RecordType.DeveloperName =='Member Outreach' &&
Any ideas on how to reference the Recordtype in the trigger?  I only want this to fire off for one of the five Task recordtypes we have.  

Thanks, 

Todd B.  
 
I created a validation rule on for the Task Object. 
 
And( 
IsBlank(Text(Activity_Type_01__c )), 
RecordType.Name = "MCC Event", 
CONTAINS(Upper(Subject), "EMAIL") = False
)
The purpose is to ensure the Activity_Type_01__c field is populated every time a task is created other than if the Task Subject contains "Email", pretty striaght forward.  The problem is, it only works when the Task is editted, it does not fire when the Task is initially created.  

Any Thoughts?

Thanks, 

Todd B.

 
Within the past couple of days I have begun receiving error emails from salesforce.  

Subject Line:  Developer script exception from $$$$$$$$$: TaskTrigger : TaskTrigger: System.LimitException: Too many SOQL queries: 101
Body Test:      Apex script unhandled trigger exception by user/organization: 0055000000118E4/00D50000000784t
                       TaskTrigger: System.LimitException: Too many SOQL queries: 101

I get two or three every hour. 

The problem is, I have not made any coding changes in the past month and the email does not give me any indication of what is causing the error.  How do I track down the problem?
Is it possible to the add the address from the "whatid" object to the Task and Event page layout?  I have a custom object with locations and addresses that I would like to display on the Task record.  I can get the location Name to appear, but can I get the address to show up?

Thanks,

Todd B.
I wrote the following Class to update a field based on a value in the User table
public with sharing class SDMR_Enrollment_Cycles_Trigger_Handler {

    Public SDMR_Enrollment_Cycles_Trigger_Handler(){
        }
    Public void OnBeforeUpdate(SD_Mbr_Enroll_Cycles__c[] newCycles){    
        For (SD_Mbr_Enroll_Cycles__c c : newcycles){

            // Look up the User Id for the Unassigned user record, to be used when the Enrollment Credit Agent 
            // field is null 
            List<User> users = [Select id, LastName from User Where LastName='Unassigned' and isActive=True
                             Limit 1];
            Map<string, string> uservalues = new Map<string, string>{};
            For(User u2: users)
                uservalues.put(u2.LastName,u2.id);
            
// Populates the Enrollment Credit Agent L/U if the Enrollment Status field = "Enrolled" and the Use Me field = True
            If(c.Enrollment_Status__c == 'Enrolled' && c.Use_Me__c == True){
                    if(c.Enrollment_Credit_Agent__c!=null){       
                        c.Enrollment_Credit_Agent_L_U__c = c.Enrollment_Credit_Agent__c;}
// If the Enrollment Credit Agent L/U is null and the Enrollment Status field = "Enrolled" and the Use Me field = True
// then look up the User Id for the Unassigned user record.
                Else {c.Enrollment_Credit_Agent_L_U__c = uservalues.get('Unassigned') ;}
                       
        }   
        }
    }    
}
But I keep getting an error when I try and validate it in prodcution.  This is the line being flagged:  
List<User> users = [Select id, LastName from User Where LastName='Unassigned' and isActive=True Limit 1];

Component Errors
Error Message
0 0 SCEBSDMEC_TEST.EnrollmentBase_Enrolled_Batchable(), Details: System.LimitException: Too many SOQL queries: 101 Class.SDMR_Enrollment_Cycles_Trigger_Handler.OnBeforeUpdate: line 10, column 1 Trigger.SDMR_Enrollment_Cycles: line 6, column 1

Apex Test Failures
Error Message
SCEBSDMEC_TEST EnrollmentBase_Enrolled_Batchable System.LimitException: Too many SOQL queries: 101 
Stack Trace: Class.SDMR_Enrollment_Cycles_Trigger_Handler.OnBeforeUpdate: line 10, column 1 Trigger.SDMR_Enrollment_Cycles: line 6, column 1
I need some help.  I created a batch process, that updates a group of records every morning.  Everything works fine in my sandbox but when I moved the code over to production and started running it, I get the following error:
Apex script unhandled exception by user/organization: ################/##################

Failed to process batch for class 'BatchUpdate_ServiceCenter_Enrollment' for job id '7075000000hItM9'

caused by: System.LimitException: Too many DML statements: 151

Class.BatchUpdate_ServiceCenter_Enrollment.execute: line 14, column

Here is the Batch Class
global class BatchUpdate_ServiceCenter_Enrollment implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Auto_Update__c FROM Enrollment_Base__c ';
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<Enrollment_Base__c> scope)
    {
        for (Enrollment_Base__c eb : scope){

         if(eb.Auto_Update__c == True)
          update eb;

        }
    }  

global void finish(Database.BatchableContext BC)
    {
   // Get the ID of the AsyncApexJob representing this batch job
    // from Database.BatchableContext.
    // Query the AsyncApexJob object to retrieve the current job's information.
    AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
                        TotalJobItems, CreatedBy.Email
                        from AsyncApexJob where Id = :BC.getJobId()];
    // Send an email to the Apex job's submitter notifying of job completion.
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[] {a.CreatedBy.Email};
    mail.setToAddresses(toAddresses);
    mail.setSubject('Batch Apex Update Event ' + a.Status);
    mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                            ' batches with '+ a.NumberOfErrors + ' failures.' );
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }

}
Here is the Update Class
public with sharing class Update_Enrollement {
/* 
  Developer     : Jim Jackson
  Created       : 08/12/2014
  Last Modified : 
  Test Class    : 
  Objective     : 
  
*/ 

    public void beforeUpdate(Enrollment_Base__c[] newlist){
        List<Date> dtStart =  new List<Date>();
        List<Date> dtEnd =  new List<Date>();
        String strKey;
        Double GMAmount = 0 ;
        Boolean strStatus ;
        String strName;

            for(Enrollment_Base__c EB : newList){
              dtStart.add(EB.Start_Date__c);    
              dtEnd.add(EB.End_Date__c);
              strKey = EB.Service_Center__c;   
              strStatus = EB.Auto_Update__c;
              strname = EB.id;
            }
                
                System.debug(strKey);
                System.debug(dtStart);
                System.debug(dtEnd);
                System.debug(strName);
           
    If(strstatus = true){
        List<aggregateResult> fpresults = [select Count(Id) Total from SD_Mbr_Enroll_Cycles__c 
                                             where Use_Me__c = True
                                             And Enrollment_Status__c = 'Enrolled'
                                             And Enrollment_Status_Date__c >= :dtStart
                                             And Enrollment_Status_Date__c <= :dtEnd
                                             And Service_Center_Id__c = :strKey.SubString(0,15)];           
        for (AggregateResult ar : fpresults )  {
            GMAmount = (Double)ar.get('Total');
                }
            
        for(Enrollment_Base__c GM : newList){
            GM.Enrolled__c =  GMamount;
            GM.id = strname; 
                }   


    }
    }
}

Here is the Trigger
trigger EnrollmentUpdating on Enrollment_Base__c (after delete, after insert, after undelete, 
after update, before delete, before insert, before update) {


if(trigger.isUpdate && trigger.isBefore){
            Update_Enrollement Handler = new Update_Enrollement();
            handler.beforeUpdate(Trigger.new); 
    }  
}

Any Ideas?

I want to create a class that will allow me, on a monthy basis, to take a list of records from one object and add it to another.

Scenerio:  I have an object Service_Center__c that has the names of all my service centers.  On a monthly basis I want to query all the Services_center__C.name and place that list of Service Centers into another custom object Quota__c.  I want it to map the following:

Services_center__C.name - Quota__c.Servicer_center_name__c
01/01/2014 - Quota__c.Period_Start_date__c (this is a date field)
0 - Quota__c.quota__c (this is an integer)

How do I go about doing this?

So I am trying to create my first batch class, and I am MORE THAN a little confused.  I created two classes.

<pre>
global class BatchUpdate_Financials implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Name,status__c FROM Financial_Planning__c ';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Financial_Planning__c> scope)
    {
        for (Financial_Planning__c fp : scope){

         if(fp.status__c == 'Active')
          update fp;

        }
    } 
    global void finish(Database.BatchableContext BC)
    {
    }
}
</pre>

<pre>
global class Scheduler_class implements Schedulable{

    public static String sched = '0 00 00 * * ?';  //Every Day at Midnight

    global static String scheduleMe() {
        Scheduler_class SC = new Scheduler_class();
        return System.schedule('My batch Job', sched, SC);
    }

    global void execute(SchedulableContext sc) {

        BatchUpdate_Financials fp = new BatchUpdate_Financials();
        ID batchprocessid = Database.executeBatch(fp,50);          
    }
}
</pre>

Then I read I have to type something like this in the Developer Console to actually schedule the job.

<pre>
Scheduler_class sch1 = New Scheduler_class();
String sch = '0 00 02 * * ?';
System.Schedulable('Financials Update', sch, sch1);
</pre>

But when i do, I get this error: "Method does not exist or incorrect signature: System.Schedulable(String, String, Scheduler_class)"

Any ideas what I am doing wrong?
Hello All, 

I recently designed a trigger to update a Goals/Forecast custom object I built called Financial_Planning__c.  Basically, on the "before update" action of the object, the trigger goes out and finds all the Closed Won opportunities for that division and updates a field on the Financial_Planning__c object.

<pre>
trigger FinancialPlanningTrigger on Financial_Planning__c (before update) {

    List<Date> dtStart =  new List<Date>();
    List<Date> dtEnd =  new List<Date>();
    List<String> strSBU =  new List<String>();
    Double fpAmount = 0 ;
String strname;

      for(Financial_Planning__c fp : trigger.new){
      dtStart.add(fp.period_start_date__c);
      dtEnd.add(fp.period_End_date__c);
      strSBU.add(fp.Division__c);
      strname = fp.division__c + ' - (' + fp.Revenue_Type__c + ')';
    }
   
List<aggregateResult> fpresults = [select Sum(amount) Total from Opportunity
               where IsWon=True
               And Contract_Start_Date__c >= :dtStart
               And Contract_Start_Date__c <= :dtEnd
               And SBU__C in :strSBU];

for (AggregateResult ar : fpresults )  {
  
    fpAmount = (Double)ar.get('Total');
}
   
      for(Financial_Planning__c fp : trigger.new){
    fp.Realized_Revenue_Actual__c =  fpamount;
    fp.name = strname; // field on which Task count and event count needs to be updated
    }
   
}
</pre>

Based on some info I heard at a developers group, I want to take the code out of the trigger and put it in a class, then have the trigger call the class?  How would I do that?  I just figured out how to create a trigger, and have not really mastered classes yet.
I am trying to create a simple trigger that checks to see if a value is changed and if so, update a few fields and create a task.  The update the few fields part works, but the create a task part does not.  I receive the error message below. 

Error Message:  Error:Apex trigger Decide_Which_Address_to_Use caused an unexpected exception, contact your administrator: Decide_Which_Address_to_Use: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []: Trigger.Decide_Which_Address_to_Use: line 78, column 1

<pre>
trigger Decide_Which_Address_to_Use on SD_Member__c (before update) {
/*
  Developer     : Todd Barry
  Created       :
  Last Modified : 03/19/2014
  Test Class    :
  Objective     :
*/

Task [] newTask = new Task[0];
// Variables
Date dtTaskDate = DateTime.now().addDays(+1).date();

For (SD_Member__c SD : Trigger.new){

SD_Member__c beforeUpdate = System.Trigger.oldMap.get(SD.Id);

if(beforeUpdate.Last_Address_Fail_Date__c != SD.Last_Address_Fail_Date__c){
      If(sd.mailing_address__c == SD.NCOA_Address__c){
    sd.Bad_NCOA_Address__c = SD.Mailing_Address__c;
          sd.Bad_NCOA_City__c = sd.Mailing_city__c;
          sd.Bad_NCOA_State__c = sd.mailing_state__c;
          sd.Bad_NCOA_Zip__c = SD.Mailing_Zip__c;
          SD.Send_Monthly_Letter__c = True; 
          newtask.add(new task(whatid=SD.Id,subject='Make 1st Follow Up Call',ActivityDate=dtTaskDate,Status='Not Started', ownerid=sd.OwnerId));
         
     }
    
  If (newtask.size()>0)  update newtask;
}
      
          
}
}
</pre>

Any ideas?

Thanks, 

Todd B.
I created the following trigger to create a chatter entry every time someone wins an opportunity

<pre>
trigger CreateChatterEntry on Opportunity (before Update) {

For(opportunity opp : Trigger.new){

// Check to see if the Oppty was previously Marked Closed Won
Opportunity beforeUpdate = System.Trigger.oldMap.get(opp.Id);
if(beforeUpdate.IsWon != opp.IsWon){

    String ownerIds = opp.Oppty_Owner_Name__c;
    String oppName = opp.name;
  
    Set<ID> ownerId = new Set<ID>();
    ownerId.add(opp.ownerId);
  
    Map<ID,User> userMap = new Map<ID,User>([SELECT ID, Name, FirstName FROM User WHERE ID In : ownerid]); //This is our user map
    User uName = userMap.get(opp.ownerId);
  
    // Get a list of All the Current Chatter Group Names
    List<CollaborationGroup> Grps = [Select Name, Id FROM CollaborationGroup];
    Map<string, String> GrpName = new Map<string, string>{};
    for(CollaborationGroup gn: Grps)
        Grpname.put(gn.name,gn.id);
  
    // If the Oppty is marked Closed Won, Create Chatter entry.
    If(opp.iswon ==true){
        FeedItem fitem = new FeedItem ();
         fitem.type = 'LinkPost';
                fitem.ParentId = grpName.get('Salesforce.com Users');  //Select What Chatter group to post message in.
                fitem.LinkUrl = '/' + opp.id; //This is the url to take the user to the activity
                fitem.Title = oppName + ' Opportunity';  //This is the title that displays for the LinkUrl
                //fitem.Body = ('Congratulations to ' + uName.name + ' on winning ' + oppname + '!  Nice Job '+ uName.firstname+'.');
                fitem.Body = ('Congratulations to ' + uName.name + ' on winning ' + oppname + '!');
        Insert fitem;
    } } 
}}
</pre>

The problem is sometimes it creates one Chatter entry and sometimes it creates two postings.  

Also, is there any way to hard code in the posting making the post.  In this case I want all post to come from me.  That way it does not look like the sales person is patting themselves on the back buy being congratulated by me.
In going through the triggers I have created, I noticed that I have created multiple trigger for the same objects.  Moving forward, is it better to create any new triggers for an object in an existing trigger, or is it ok to continue creating additional triggers on the same object.
I am trying to create a Chatter post from a visual workflow.  When an Oppty is won, I want to create a Chatter post congratulating the Oppty owner and have it come from their Manager.  So far I can I can do all that using the Create Record Action
User-added image

The issue I am running into, I want to @mention the Manager (so they know they "sent" a chatter post) so I created a text body formula:
User-added image 
but the Chatter post is listing the id, and not doing a true @mention
User-added image

Any ideas on how to do a proper @mention via a formula?

Thanks, 

Todd B. 
 
I created the following trigger to create a chatter entry every time someone wins an opportunity

<pre>
trigger CreateChatterEntry on Opportunity (before Update) {

For(opportunity opp : Trigger.new){

// Check to see if the Oppty was previously Marked Closed Won
Opportunity beforeUpdate = System.Trigger.oldMap.get(opp.Id);
if(beforeUpdate.IsWon != opp.IsWon){

    String ownerIds = opp.Oppty_Owner_Name__c;
    String oppName = opp.name;
  
    Set<ID> ownerId = new Set<ID>();
    ownerId.add(opp.ownerId);
  
    Map<ID,User> userMap = new Map<ID,User>([SELECT ID, Name, FirstName FROM User WHERE ID In : ownerid]); //This is our user map
    User uName = userMap.get(opp.ownerId);
  
    // Get a list of All the Current Chatter Group Names
    List<CollaborationGroup> Grps = [Select Name, Id FROM CollaborationGroup];
    Map<string, String> GrpName = new Map<string, string>{};
    for(CollaborationGroup gn: Grps)
        Grpname.put(gn.name,gn.id);
  
    // If the Oppty is marked Closed Won, Create Chatter entry.
    If(opp.iswon ==true){
        FeedItem fitem = new FeedItem ();
         fitem.type = 'LinkPost';
                fitem.ParentId = grpName.get('Salesforce.com Users');  //Select What Chatter group to post message in.
                fitem.LinkUrl = '/' + opp.id; //This is the url to take the user to the activity
                fitem.Title = oppName + ' Opportunity';  //This is the title that displays for the LinkUrl
                //fitem.Body = ('Congratulations to ' + uName.name + ' on winning ' + oppname + '!  Nice Job '+ uName.firstname+'.');
                fitem.Body = ('Congratulations to ' + uName.name + ' on winning ' + oppname + '!');
        Insert fitem;
    } } 
}}
</pre>

The problem is sometimes it creates one Chatter entry and sometimes it creates two postings.  

Also, is there any way to hard code in the posting making the post.  In this case I want all post to come from me.  That way it does not look like the sales person is patting themselves on the back buy being congratulated by me.
I have written a basic VF page to view and add phone numbers to a custom object.  The page and the controller work, but I can not figure out the test class.  I am receiving an error message that I am missing a required field.

VF Page:
<apex:page standardController="Task"  extensions="CurrentPhoneRecords_controller" sidebar="false" showHeader="false">
<apex:form >

    <apex:pageBlock >
        <apex:pageBlockSection id="MemberSummary" title="Member Summary" showheader="true" columns="2">
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.First_Name__c}"/>
            <apex:outputField Label="Age" value="{!Task.SD_Member_Stakeholders__r.Age_SD_Member__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Last_Name__c}"/>
            <apex:outputField Label="DOB" value="{!Task.SD_Member_Stakeholders__r.Date_of_Birth__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_Address__c}"/>
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Phone_Last_Research_Date__c}"/>   
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_City__c}"/>
            <apex:outputField Label="Click to View Member Record" value="{!Task.WhatId}"/>       
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Mailing_State__c}"/>    
            <apex:outputField value="{!Task.SD_Member_Stakeholders__r.Intelius_Search_Link__c}"/>
        </apex:pageBlockSection>
    </apex:pageBlock>
  

<!-- Add a New Phone Number-->
    <apex:actionregion >
        <apex:outputPanel id="AddPhoneNumber" >
            <apex:pageBlock title="Add a New Phone Number" rendered="True">
                <apex:pageBlockButtons location="top" >    <!-- component to contain all the buttons, can show buttons on top, bottom of the record or both -->
                    <apex:commandButton value="New" action="{!newPH}" reRender="AddPhoneNumber" rendered="{!!editPH}"  >
                        <apex:param name="editPH" value="true" assignTo="{!editPH}"/>
                    </apex:commandButton>
                    <apex:commandButton value="Save" action="{!savePH}"  rerender="AddPhoneNumber, PhoneList" rendered="{!editPH}">
                        <apex:param name="SavePH" value="False" assignTo="{!editPH}"/>
                    </apex:commandButton>                    
                    <apex:commandButton value="Save & New" action="{!savenewPH}"  rerender="AddPhoneNumber, PhoneList" rendered="{!editPH}">
                        <apex:param name="SavePH" value="True" assignTo="{!editPH}"/>
                    </apex:commandButton>
<!-- The Cancel Button is not working yet
                    <apex:commandButton value="Cancel" immediate="true" rerender="AddPhoneNumber" rendered="{!editPH}" >
                        <apex:param name="cancelPH" value="false" assignTo="{!editTask}"/>
                    </apex:commandButton>                    
-->
                </apex:pageBlockButtons>
        <apex:pageBlockSection columns="2" >
<!-- View only Fields
           <apex:outputField value="{!ph.Phone_Number__c}" rendered="{!!editPH}" />
           <apex:outputField value="{!ph.Phone_Number_Status__c}" rendered="{!!editPH}" />
           <apex:outputField value="{!ph.Phone_Type__c}" rendered="{!!editPH}" />
-->           
<!-- Add New Phone Number Fields-->
           <apex:inputField value="{!ph.Phone_Number__c}" rendered="{!editPH}" />
           <apex:inputField value="{!ph.Phone_Number_Status__c}" rendered="{!editPH}" />
           <apex:inputField value="{!ph.Phone_Type__c}" rendered="{!editPH}" /> 
         </apex:pageBlockSection>
            </apex:pageBlock>
        </apex:outputPanel>
    </apex:actionregion>

<apex:actionRegion >
    <apex:pageBlock >
        <apex:pageBlockSection id="PhoneList" title="Current Phone Numbers" showHeader="true" columns="1" onclick="saveState(this);">
            <apex:pageBlockTable value="{!PhoneRecords}" var="i" width="100%" border="1" cellspacing="2" cellpadding="2"  >
                <apex:column value="{!i.Phone_Number__c}"/> 
                <apex:column value="{!i.Phone_Number_Status__c}"/> 
                <apex:column value="{!i.Phone_Type__c}"/> 
            </apex:pageBlockTable>
       </apex:pageBlockSection>
    </apex:pageBlock> 
</apex:actionRegion>    

</apex:form>                                        
</apex:page>



Controller:
/*
  Class        : CurrentPhoneRecords
  Developer    : Todd Barry
  Created      : June 1, 2018
  Objective    : Controller for PRM vsiualforce page. 
  Updates      :              
*/

 public class CurrentPhoneRecords_controller {

    Private Task T1;
    Public Phone_Numbers__c PhoneRecords;
    Public boolean editPR {get;set;}                //store boolean variable for making fields editable

    public string sObjectName02 = 'Phone_Numbers__c';//string specifying object name for use in dynamic query
    public string sObjectFields02 {get;set;}         //string that will hold csv of all fields on SDMember
    public string sObjectID02 {get;set;}             //parameter which will be assigned from visualforce page and used to query SDMember with the given ID
    public string sObjectSOQL02 {get;set;}           //string of the complete SOQL query that returns all fields on SDMember
    public string strSDMemberID {get;set;}    
    
    
    public Phone_Numbers__c PH {get;set;}
    public id PHID {get;set;}                        //Phone Number id from SOQL query
    public boolean editPH {get;set;}
    
    public CurrentPhoneRecords_Controller(ApexPages.StandardController controller) {
        this.t1= (Task)Controller.getRecord();        
}
    
                
    
     Public List <Phone_Numbers__c> getPhoneRecords() {
     
        Task t2 = [Select id, whatid from Task where id = :t1.id];  
        strSDMemberID = t2.whatid;       
    
        List <Phone_Numbers__c> PhoneRecords = [Select Id,
                                                Phone_Number__c,
                                                Phone_Number_Status__c,
                                                Phone_Type__c,
                                                Override_Request_Status__c,
                                                SD_Member_Link__c 
                                                From Phone_Numbers__c 
                                                Where SD_Member_Link__c = :t2.whatid];
        return PhoneRecords;                                        
    
    }
    
   Public Void SavePhoneRecords() {
        if(PhoneRecords.id == Null)
            insert PhoneRecords;
        Else
            update Phonerecords; 
    }      
// Adding a new phone number
 public void getPH(){      // retrieve selected task
      
        sObjectFields02 = '';                          //initialize as an emply string to prevent 'null field__c, ...'
        //get the object then get the fields and then field names (returns a list and itterates through it)
        for(string field : schema.getglobaldescribe().get(sObjectName02).getdescribe().fields.getmap().keyset()){
           sObjectFields02 += field + ', ';           //build string of all fields on the given sObject
        }
        sObjectFields02 = sObjectFields02.substring(0,sObjectFields02.length()-2);    //remove the trailing comma
        sObjectFields02+=', lastmodifiedby.name';

        sObjectSOQL02 = 'select ' + sObjectFields02 + ' from ' + sObjectName02 + ' where id = \'' + sObjectId02 +'\'';    //build complete query statement for SDMember which includes all the fields for easy reference
        System.debug (sObjectSOQL02);
        PH = Database.query(sObjectSOQL02);             
 
    }
    
    Public void newPH(){
    PH = New Phone_Numbers__c();
    ph.Phone_Number_Status__c ='Not Called Yet';
    Ph.Phone_Type__c = 'Intelius';
    ph.SD_Member_Link__c = strSDMemberID;

    
    }
    
    public void savePH(){
        if(ph.id == null)         // if new task then insert
            insert PH;
        else
            update PH;            // otherwise update task
    }        
    
        public void savenewPH(){
        if(ph.id == null)         // if new task then insert
            insert PH;
            // Create New PH entry
            PH = New Phone_Numbers__c();
            ph.Phone_Number_Status__c ='Not Called Yet';
            Ph.Phone_Type__c = 'Intelius';
            ph.SD_Member_Link__c = strSDMemberID;
    
    }
         
}

 Test Class:
@isTest
public class TestClass_Outreach_Console_Controller {

    static testMethod void myUnitTest() {
        // TO DO: implement unit test

date dtTestDate  = System.today() + 5;

        // Create User Record 
User u1 = [SELECT Id FROM User Where isActive=True  LIMIT 1];

//Create Service Center
Service_Center__c SC = new Service_Center__c(Name='Test1');
Insert sc;


// Create SD Member Record
SD_Member__c sd = New SD_Member__c(First_Name__c = 'John', 
                                   Last_Name__c = 'Smith', 
                                   Ins_ID_Member__c = '123456', 
                                   Ins_ID_Suscriber__c = '456789',
                                   address__c = '123 Main Street', 
                                   city__c = 'Aster', 
                                   state__c = 'CT', 
                                   zip__c = '06001', 
                                   name = 'John Smith',
                                   Lost_Contact_Follow_Up__c = False,
                                   Mailing_Cycle__c='Week 2.1',
                                   Total_Opt_out__c = False,
                                   Catasys_Stops_Phone_Follow_Ups__c=False,
                                   P10M_Impactable_Cost__c=500,
                                   Work_Phone__c='8607985214',
                                   Member_Eligibility_Status__c='Eligible',
                                   Service_Center__c=sc.id,
                                   Referral_Source__c='Claims Data',
                                   Catasys_Medical_Exclusion_Status__C='Medically Targeted',
                                   Enrollment_Progress_Status__c='Attempting to Contact',
                                   Post_Referral_to_CC_Status__c='Pre Referral',
                                   Carecoach__c = u1.id);
insert sd;

// Create New Phone Record
Phone_Numbers__c phTest = New Phone_Numbers__c(SD_Member_Link__c = sd.id,
                                           Phone_Number__c = '8951239874',
                                           Phone_Type__c = 'Home',
                                           Phone_Number_Status__c = 'Not Called Yet');
insert phTest;        
                                           
        

Task t11 = new Task();
t11.WhatId=sd.id;
t11.Subject = '[Phone Number Research]'; //set the required fields
t11.Status ='In Progress';
t11.ActivityDate = dtTestDate;        
Insert t11;        

Id taskID;
taskID = t11.Id;


 
// Test the currentPhoneRecords_Controller
	ApexPages.StandardController stdController = new ApexPages.StandardController(t11);
        CurrentPhoneRecords_controller cpr = new CurrentPhoneRecords_controller(stdController);
        
        cpr.getPhoneRecords();
        
        cpr.newPH();
        
        cpr.ph.Phone_Number__c = '1234567890';
        
        cpr.savenewPH();
        cpr.savePH();
        
      
    }
}

The issue i am having is with this line:  cpr.ph.Phone_Number__c = '1234567890';.  I am trying to input a new phone number to test the savenewPH and save PH methods.  The error I am receving is System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Phone_Number__c]: [Phone_Number__c] 

How do I set the value of an inputfield in the VF page? 
 
I have been handed a fairly complex VF page to update.  The are several sections on the page, call updated by clicking on a row in a table.  The issue I am having is, when some updates one of the subsections on the page, I need the entire page to refresh.  Currently, I have a two button process, the first button is the standard "Save" functionality:
<apex:commandButton value="Save" action="{!saveTask}" status="loadSDMember" oncomplete="RefreshText();" rerender="taskDetail, SDMember,  SDMemberSummary, PhoneDetail,  debug" rendered="{!editTask}">

<apex:param name="editTask" value="false" assignTo="{!editTask}"/>
                                        
</apex:commandButton>
Then I created a second button to refresh the page
<apex:commandButton value="Press Here After Saving" action="{!getSDMember}" status="loadSDMember" oncomplete="RefreshText();" rerender="taskDetail, SDMember,  SDMemberSummary, PhoneDetail,  debug">
                                       
<apex:param name="taskID" value="{!task.id}" assignto="{!taskID}" />                                        <apex:param name="editMode" value="false" assignto="{!editMode}" />                                        <apex:param name="editTask" value="false" assignto="{!editTask}" />                                        <apex:param name="viewFullRecord" value="false" assignto="{!viewFullRecord}" />                            <apex:param name="SDMemberID" value="{!SDMember.id}" assignto="{!sObjectID}" />
<apex:param name="PHID" Value="" assignTo="{!sObjectid02}" />

</apex:commandButton>

Is it possible to combined this into just one button?
Since you can not use workflows to send an email update on a Event, I am working on creating a trigger that will send email.  I created an email template called MCC_Close_Event_Email and based it on the Event object.  I tested it and made sure it pulls all the correct info when sending.  

Then I created the trigger below to send the email when a cretain field is checked.  
trigger EventSendEmailMCCReminder on Event (After Update, After Insert) {

/*  Event e1 = trigger.new[0];  */
    For (Event e1 : trigger.New){
  String[] toAddresses = new String[] {e1.owner.email};
  String[] strProfile = New String[] {e1.owner.profile.name};    
  Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

  mail.setTargetObjectId(e1.OwnerID);
  mail.setSenderDisplayName('Salesforce Admin');
  mail.setUseSignature(false);
  mail.setBccSender(false);
  mail.setSaveAsActivity(false);  
  
  System.debug('Profile Name ' + e1.owner.profile.name);
  System.debug('Owner Name ' + e1.owner.name);  
  System.debug('Profile Name ' + strProfile);
  System.debug('To Address ' + toAddresses);        
    
	If(e1.SendMCCRemiderEmail__c == True ){
 /*       If(e1.owner.profile.name == 'System Administrator'){ */
		EmailTemplate et=[Select id from EmailTemplate where DeveloperName=:'MCC_Close_Event_Email'];
        mail.setTemplateId(et.id);
        Messaging.SendEmailResult [] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});         
    }   
    }  
}
My issue is, it send the email, but all the Event related fields in the email are blank.  Also, all me System.Debug values are blank in the debug log.  

Any ideas to ensure the Event related fields in the Email are populated?
 
Hello All, 

I am new to writing Apex code and was able to wrtite the following piece to calculate both Divisional and Individual Sales goals.
 
public with sharing class FinancialPlanningTriggerHandle {
/* 
  Developer     : Todd Barry
  Created       : 05/27/2014
  Last Modified : 
  Test Class    : 
  Objective     : 
  
*/      
    public void beforeUpdate(Financial_Planning__c[] newlist){
        List<Date> dtStart =  new List<Date>();
        List<Date> dtEnd =  new List<Date>();
        List<String> strKey =  new List<String>();
        String strGT ;
        Double fpAmount = 0 ;
        String strname;
        
            for(Financial_Planning__c fp : newList){
              StrGT = fp.GoalType__c;
              dtStart.add(fp.period_start_date__c); 
              dtEnd.add(fp.period_End_date__c);
              strKey.add(fp.rptKey__c); 
              strname = fp.period_start_date__c.year() +' - ' +fp.division__c + ' - (' + fp.Revenue_Type__c + ')';
            }
                System.debug(strKey);
                System.debug(dtStart);
                System.debug(dtEnd);
                System.debug(strName);
                
        //Determine Which Recordtype you are working with
        if(strGT == 'Divisional Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }
        if(strGT == 'Personal Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }        
        
        
        
        
        }
    }

What I can not figure out is how to streamline some of the code.  I want to take this section and combined it into one IF statement:
//Determine Which Recordtype you are working with
        if(strGT == 'Divisional Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }
        if(strGT == 'Personal Goal'){
             List<aggregateResult> fpresults = [select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
                                                
        
            for (AggregateResult ar : fpresults )  {
                fpAmount = (Double)ar.get('Total');
            }
        
            for(Financial_Planning__c fp : newList){
                fp.Realized_Revenue_Actual__c =  fpamount;
                fp.name = strname; 
            }   
        }

Basically, I want something like this:  

  if(strGT == 'Divisional Goal'){
      String A = select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_div__c = :strKey];
Else string A = select Sum(Incremental_Annualized_Revenue__c) Total from Opportunity 
                                                 where IsWon=True
                                                 And Contract_Start_Date__c >= :dtStart
                                                 And Contract_Start_Date__c <= :dtEnd
                                                 And rptFinancialKey_User__c = :strKey];
             
Then 

List<aggregateResult> fpresults = String A

But I am not sure how to do it.  Any ideas?

Regards, 

Todd B.
Hello All, 

I am trying to write a trigger for a certain Task record type
 
trigger Update_SD_Member_Enrollment_Progress_Status on Task (after update) {
/*
Automatically update the "Enrollment Progress Status" field, based upon the "Status" field 
of the last Member Task
*/

// Tasks that meet criteria, and new tasks to create
Task[] qualifiedTasks = new Task[0], newTasks = new Task[0];

Date dt=DateTime.now().addDays(1).date();
Date rt=DateTime.now().addDays(1).date();
    
// Map of SD Members
   Map<Id,SD_Member__c> members = new Map<Id,SD_Member__c>();

// Find qualifying tasks
for(Task record:Trigger.new)
     if(Record.RecordType.DeveloperName =='Member Outreach' &&
           record.isclosed == True)
           qualifiedtasks.add(record);
    
    // Obtain member ID values
    for(Task record:qualifiedtasks)
        members.put(record.whatid,null);
   
    // If there are any members to query, do so.
    if(!members.isempty())
        members.putall([select id, Enrollment_Progress_Status__c from SD_Member__c where id in :members.keyset()]);


 // For each qualifying task, check the current Enrollment_Progress_Status__c from SD_Member__c and assign
 // to the strStatus variable.  That way if the Task Status does not meet the critera below, the status 
 // will reamin it's current value 
for(Task record:qualifiedtasks) {
    String strStatus = members.get(record.whatid).Enrollment_Progress_Status__c;    

    // Set the strStatus based on the current Task Status value
      If (record.Status == 'Not Started' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Left Message w/ Person' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Member Hung Up' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Phone # Invalid' ){
          StrStatus = 'Phone # Invalid';}
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';} 
      If (record.Status == 'Reached Recording - No Msg Left' ){
          StrStatus = 'Attempting to Contact';}              
      If (record.Status == 'Reached Target - Call Later' ){
          StrStatus = 'Successful Contact';}
      If (record.Status == 'Reached Target - Declined - Copay' ){
          StrStatus = 'Declined - Copay';}
      If (record.Status == 'Reached Target - Declined - Other' ){
          StrStatus = 'Declined - Other';}
      If (record.Status == 'Reached Target - Declined - Transport' ){
          StrStatus = 'Declined - Transportation';}
      If (record.Status == 'Reached Target - Requested Info' ){
          StrStatus = 'Decision Pending';}
      If (record.Status == 'Reached Target - Sent to Care Coach' ){
          StrStatus = 'Referred to Care Coach';}
      If (record.Status == 'Reached Target - Thinking About It' ){
          StrStatus = 'Decision Pending';}
          
    SD_Member__C SD1 = new SD_Member__C(ID=record.WhatId,Enrollment_Progress_Status__c=strStatus);
    update SD1; 
    
    }  }

But it keeps ignoring the line 
if(Record.RecordType.DeveloperName =='Member Outreach' &&
Any ideas on how to reference the Recordtype in the trigger?  I only want this to fire off for one of the five Task recordtypes we have.  

Thanks, 

Todd B.  
 
I created a validation rule on for the Task Object. 
 
And( 
IsBlank(Text(Activity_Type_01__c )), 
RecordType.Name = "MCC Event", 
CONTAINS(Upper(Subject), "EMAIL") = False
)
The purpose is to ensure the Activity_Type_01__c field is populated every time a task is created other than if the Task Subject contains "Email", pretty striaght forward.  The problem is, it only works when the Task is editted, it does not fire when the Task is initially created.  

Any Thoughts?

Thanks, 

Todd B.

 
I need some help.  I created a batch process, that updates a group of records every morning.  Everything works fine in my sandbox but when I moved the code over to production and started running it, I get the following error:
Apex script unhandled exception by user/organization: ################/##################

Failed to process batch for class 'BatchUpdate_ServiceCenter_Enrollment' for job id '7075000000hItM9'

caused by: System.LimitException: Too many DML statements: 151

Class.BatchUpdate_ServiceCenter_Enrollment.execute: line 14, column

Here is the Batch Class
global class BatchUpdate_ServiceCenter_Enrollment implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Auto_Update__c FROM Enrollment_Base__c ';
        return Database.getQueryLocator(query);
    }
 
    global void execute(Database.BatchableContext BC, List<Enrollment_Base__c> scope)
    {
        for (Enrollment_Base__c eb : scope){

         if(eb.Auto_Update__c == True)
          update eb;

        }
    }  

global void finish(Database.BatchableContext BC)
    {
   // Get the ID of the AsyncApexJob representing this batch job
    // from Database.BatchableContext.
    // Query the AsyncApexJob object to retrieve the current job's information.
    AsyncApexJob a = [Select Id, Status, NumberOfErrors, JobItemsProcessed,
                        TotalJobItems, CreatedBy.Email
                        from AsyncApexJob where Id = :BC.getJobId()];
    // Send an email to the Apex job's submitter notifying of job completion.
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[] {a.CreatedBy.Email};
    mail.setToAddresses(toAddresses);
    mail.setSubject('Batch Apex Update Event ' + a.Status);
    mail.setPlainTextBody('The batch Apex job processed ' + a.TotalJobItems +
                            ' batches with '+ a.NumberOfErrors + ' failures.' );
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
    }

}
Here is the Update Class
public with sharing class Update_Enrollement {
/* 
  Developer     : Jim Jackson
  Created       : 08/12/2014
  Last Modified : 
  Test Class    : 
  Objective     : 
  
*/ 

    public void beforeUpdate(Enrollment_Base__c[] newlist){
        List<Date> dtStart =  new List<Date>();
        List<Date> dtEnd =  new List<Date>();
        String strKey;
        Double GMAmount = 0 ;
        Boolean strStatus ;
        String strName;

            for(Enrollment_Base__c EB : newList){
              dtStart.add(EB.Start_Date__c);    
              dtEnd.add(EB.End_Date__c);
              strKey = EB.Service_Center__c;   
              strStatus = EB.Auto_Update__c;
              strname = EB.id;
            }
                
                System.debug(strKey);
                System.debug(dtStart);
                System.debug(dtEnd);
                System.debug(strName);
           
    If(strstatus = true){
        List<aggregateResult> fpresults = [select Count(Id) Total from SD_Mbr_Enroll_Cycles__c 
                                             where Use_Me__c = True
                                             And Enrollment_Status__c = 'Enrolled'
                                             And Enrollment_Status_Date__c >= :dtStart
                                             And Enrollment_Status_Date__c <= :dtEnd
                                             And Service_Center_Id__c = :strKey.SubString(0,15)];           
        for (AggregateResult ar : fpresults )  {
            GMAmount = (Double)ar.get('Total');
                }
            
        for(Enrollment_Base__c GM : newList){
            GM.Enrolled__c =  GMamount;
            GM.id = strname; 
                }   


    }
    }
}

Here is the Trigger
trigger EnrollmentUpdating on Enrollment_Base__c (after delete, after insert, after undelete, 
after update, before delete, before insert, before update) {


if(trigger.isUpdate && trigger.isBefore){
            Update_Enrollement Handler = new Update_Enrollement();
            handler.beforeUpdate(Trigger.new); 
    }  
}

Any Ideas?

I want to create a class that will allow me, on a monthy basis, to take a list of records from one object and add it to another.

Scenerio:  I have an object Service_Center__c that has the names of all my service centers.  On a monthly basis I want to query all the Services_center__C.name and place that list of Service Centers into another custom object Quota__c.  I want it to map the following:

Services_center__C.name - Quota__c.Servicer_center_name__c
01/01/2014 - Quota__c.Period_Start_date__c (this is a date field)
0 - Quota__c.quota__c (this is an integer)

How do I go about doing this?

So I am trying to create my first batch class, and I am MORE THAN a little confused.  I created two classes.

<pre>
global class BatchUpdate_Financials implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Name,status__c FROM Financial_Planning__c ';
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Financial_Planning__c> scope)
    {
        for (Financial_Planning__c fp : scope){

         if(fp.status__c == 'Active')
          update fp;

        }
    } 
    global void finish(Database.BatchableContext BC)
    {
    }
}
</pre>

<pre>
global class Scheduler_class implements Schedulable{

    public static String sched = '0 00 00 * * ?';  //Every Day at Midnight

    global static String scheduleMe() {
        Scheduler_class SC = new Scheduler_class();
        return System.schedule('My batch Job', sched, SC);
    }

    global void execute(SchedulableContext sc) {

        BatchUpdate_Financials fp = new BatchUpdate_Financials();
        ID batchprocessid = Database.executeBatch(fp,50);          
    }
}
</pre>

Then I read I have to type something like this in the Developer Console to actually schedule the job.

<pre>
Scheduler_class sch1 = New Scheduler_class();
String sch = '0 00 02 * * ?';
System.Schedulable('Financials Update', sch, sch1);
</pre>

But when i do, I get this error: "Method does not exist or incorrect signature: System.Schedulable(String, String, Scheduler_class)"

Any ideas what I am doing wrong?
All,

I have a requirement in which I have to create a record in which I can select the owner, not default to the login user as the owner. IS there any way to accomplish this?

Regards

Hello All, 

I recently designed a trigger to update a Goals/Forecast custom object I built called Financial_Planning__c.  Basically, on the "before update" action of the object, the trigger goes out and finds all the Closed Won opportunities for that division and updates a field on the Financial_Planning__c object.

<pre>
trigger FinancialPlanningTrigger on Financial_Planning__c (before update) {

    List<Date> dtStart =  new List<Date>();
    List<Date> dtEnd =  new List<Date>();
    List<String> strSBU =  new List<String>();
    Double fpAmount = 0 ;
String strname;

      for(Financial_Planning__c fp : trigger.new){
      dtStart.add(fp.period_start_date__c);
      dtEnd.add(fp.period_End_date__c);
      strSBU.add(fp.Division__c);
      strname = fp.division__c + ' - (' + fp.Revenue_Type__c + ')';
    }
   
List<aggregateResult> fpresults = [select Sum(amount) Total from Opportunity
               where IsWon=True
               And Contract_Start_Date__c >= :dtStart
               And Contract_Start_Date__c <= :dtEnd
               And SBU__C in :strSBU];

for (AggregateResult ar : fpresults )  {
  
    fpAmount = (Double)ar.get('Total');
}
   
      for(Financial_Planning__c fp : trigger.new){
    fp.Realized_Revenue_Actual__c =  fpamount;
    fp.name = strname; // field on which Task count and event count needs to be updated
    }
   
}
</pre>

Based on some info I heard at a developers group, I want to take the code out of the trigger and put it in a class, then have the trigger call the class?  How would I do that?  I just figured out how to create a trigger, and have not really mastered classes yet.
I am trying to create a simple trigger that checks to see if a value is changed and if so, update a few fields and create a task.  The update the few fields part works, but the create a task part does not.  I receive the error message below. 

Error Message:  Error:Apex trigger Decide_Which_Address_to_Use caused an unexpected exception, contact your administrator: Decide_Which_Address_to_Use: execution of BeforeUpdate caused by: System.DmlException: Update failed. First exception on row 0; first error: MISSING_ARGUMENT, Id not specified in an update call: []: Trigger.Decide_Which_Address_to_Use: line 78, column 1

<pre>
trigger Decide_Which_Address_to_Use on SD_Member__c (before update) {
/*
  Developer     : Todd Barry
  Created       :
  Last Modified : 03/19/2014
  Test Class    :
  Objective     :
*/

Task [] newTask = new Task[0];
// Variables
Date dtTaskDate = DateTime.now().addDays(+1).date();

For (SD_Member__c SD : Trigger.new){

SD_Member__c beforeUpdate = System.Trigger.oldMap.get(SD.Id);

if(beforeUpdate.Last_Address_Fail_Date__c != SD.Last_Address_Fail_Date__c){
      If(sd.mailing_address__c == SD.NCOA_Address__c){
    sd.Bad_NCOA_Address__c = SD.Mailing_Address__c;
          sd.Bad_NCOA_City__c = sd.Mailing_city__c;
          sd.Bad_NCOA_State__c = sd.mailing_state__c;
          sd.Bad_NCOA_Zip__c = SD.Mailing_Zip__c;
          SD.Send_Monthly_Letter__c = True; 
          newtask.add(new task(whatid=SD.Id,subject='Make 1st Follow Up Call',ActivityDate=dtTaskDate,Status='Not Started', ownerid=sd.OwnerId));
         
     }
    
  If (newtask.size()>0)  update newtask;
}
      
          
}
}
</pre>

Any ideas?

Thanks, 

Todd B.
In going through the triggers I have created, I noticed that I have created multiple trigger for the same objects.  Moving forward, is it better to create any new triggers for an object in an existing trigger, or is it ok to continue creating additional triggers on the same object.
I wrote the following trigger to pull the Max date from a child record.  The problem is, it is not pulling the Max value it's pulling the value of the last child record entered.  I tried using the Select Max(Enrollment_Status_Date__c) but I receved an error, Malformed Query - Only root queries support aggregate expressions.

Any ideas how to get the max value?

<pre>
trigger Update_Latest_Enrollment_Date_v02 on SD_Mbr_Enroll_Cycles__c (after insert, after update) {

Map<id,SD_Member__C> SDM = New Map<id,SD_Member__C>();
List<id> sdId = New List<id>();

For (SD_Mbr_Enroll_Cycles__c sdec : Trigger.new) {
        sdid.add(sdec.SD_Member_Stakeholders__c);}

System.debug(sdid);

SDM =  New Map<id,SD_Member__C>([Select Id, Name, Enrollment_Date_Latest_OnTrak__c,
                                (select SD_Member_Stakeholders__c, Enrollment_Status__c, Enrollment_Status_Date__c
                                          From SD_Mbr_Enroll_Cycles__r
                                          Where Use_Me__c = True
                                          and Enrollment_Status__c = 'Enrolled'
                                          ORDER BY Enrollment_Status_Date__c DESC LIMIT 1)
                                From  SD_Member__c
                                Where ID IN : sdid ]);
                           
For(SD_Mbr_Enroll_Cycles__c EC: Trigger.new){
    SD_member__c sd1 = sdm.get(ec.SD_Member_Stakeholders__c);
    sd1.Enrollment_Date_Latest_OnTrak__c = ec.Enrollment_Status_Date__c;
   
    System.debug(ec.Enrollment_Status_Date__c);
}

Update sdm.values();

}
</pre>
I wrote this piece of code to select the Max value from a series of Child records for a Parent reocrd that in not in a Master Detail.  Basically the Parent Record SD_Member__c can have enerous Child records - SD_Mbr_Enroll_Cycles__c.  So I want to capture the Max Enrollment_Status_Date__c and update a field on the Parent Record.  

I wrote the following code and it works but I know there is a better way to write this.  
 
trigger Update_Latest_Enrollment_Date on SD_Mbr_Enroll_Cycles__c (after insert, after update) {
/*
  Developer     : Todd Barry
  Created       :
  Last Modified : 02/26/2014
  Test Class    : Test_Last_Enrollment_Logic
  Objective     : Update the corresponding Enrollment Date (Latest) - OnTrak Field on the SD Member record.
*/
For (SD_Mbr_Enroll_Cycles__c EC : Trigger.new){

String strId = ec.SD_Member_Stakeholders__c;

List <SD_Mbr_Enroll_Cycles__c> ec1 = [select Enrollment_Status__c, Enrollment_Status_Date__c from SD_Mbr_Enroll_Cycles__c
                                       Where SD_Member_Stakeholders__c =: Strid
                                       And Use_Me__c = True
                                       and Enrollment_Status__c = 'Enrolled'
                                       ORDER BY Enrollment_Status_Date__c DESC LIMIT 1];

Map<string,Date> MaxDate = New Map<string,Date>{};
For (SD_Mbr_Enroll_Cycles__c ec2: ec1)
MaxDate.put(ec2.Enrollment_Status__c, ec2.Enrollment_Status_Date__c) ;                                     
                                      
// Not sure I need this line.
//For (SD_Member__c sd : [Select id,Enrollment_Date_Latest_OnTrak__c From SD_Member__c Where id =: strId]){

Sd_Member__C sd1 = new Sd_member__c (id = strId,
          Enrollment_Date_Latest_OnTrak__c = maxdate.get('Enrolled'));

Update sd1;        
         
                       
}
}
Hi,

I have defined Apex triggers on after insert which will fire the email on per case basis. Issue is same email is firing twice. Could any one help to get it solve..

trigger sendEmail on Case (after insert,after update) {
    Public static Boolean InitialEmail =false;
  
     for(Case c:trigger.new) {
       
        system.debug('outside'+c.Send_Email_to_Contact__c);
       
        if ((trigger.isInsert || (trigger.oldMap.get(c.Id).Send_Email_to_Contact__c != c.Send_Email_to_Contact__c)) && (c.Send_Email_to_Contact__c && !c.Do_not_Send_Email__c  && c.Email_of_Complainant__c!=null && c.Status!='Completed')) {
               
                system.debug('??????'+c.Send_Email_to_Contact__c);
              
                    sendEmailMessage(c.id,c.ownerId,c.Internal_Comments__c,c.Email_of_Complainant__c,c.Site_Details__c,c.CaseNumber,c.Case_Customer_Reference__c );
        }
       
}