• Andrew Telford
  • NEWBIE
  • 70 Points
  • Member since 2015
  • CommInsure


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 15
    Questions
  • 21
    Replies
I am having issues with the CPU limit when sending out emails. The ideal scenario is to be able to send out 1000 emails in a hit but if I try that it exceeds the limits of the CPU. I can send 150 a time which is good but not entirely the best option for use at this point.

I am sending it this way rather than via ExactTarget or similar as we don't currently have connections to these services and we are sending attachments to the recipients.

Any thoughts as to where I should start to reduce the CPU impact so that I can increase the number of emails that I can send in one schedule execution?

Screen shot of Log File

 
//------------------------------------------------------------------------------------------------------
    //--
    //--    send_mailout
    //--
    //--    Use:
    //--    This is the process to actually send the email and will be triggered by a scheduled APEX
    //--
    //--
    //------------------------------------------------------------------------------------------------------
    PUBLIC VOID send_mailout(STRING mailOutName, INTEGER iTotalSend)
    {
        //--    Our variables
        BOOLEAN sndSuccess = FALSE;
        
        strTemplate_Initial = mailOutName;
        strTemplate_Password = mailOutName + ' - Password';

        //--    Set the FROM email address
        //--	------------------------------------
        for(OrgWideEmailAddress owa : [SELECT id, Address, DisplayName FROM OrgWideEmailAddress WHERE DisplayName = 'CommInsure Communications']) 
        {
            strEmailFrom = owa.id;
        } 

        //--    Get the details of who we are going to send to
        //--	----------------------------------------------------
        objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c 
                      FROM ci_mailout__c 
                      WHERE Sent__c = FALSE 
                      AND Mailout_name__c = :strTemplate_Initial 
                      ORDER BY Policy_count__C Desc 
                      LIMIT :iTotalSend];
        FOR( ci_mailout__c mo : objMailout )
        {	mailoutIDs.add( mo.Id );	}

        //--	Create some attachment maps
        MAP<ID, String> mName = NEW MAP<ID, String>();
        MAP<ID, BLOB> mBody = NEW MAP<ID, BLOB>();
        MAP<ID, String> mContentType = NEW MAP<ID, String>();
        objAttachment = [SELECT ID, ParentID, Name, ContentType, body FROM attachment WHERE ParentId IN :mailoutIDs];
        FOR( attachment thisAttachment : objAttachment )
        {
            mName.put( thisAttachment.ParentID, thisAttachment.Name );
            mBody.put( thisAttachment.ParentID, thisAttachment.body );
            mContentType.put( thisAttachment.ParentID, thisAttachment.ContentType );
        }
        
        SYSTEM.debug(thisScript + 'Size of Mailout: ' + objMailout.size());

        //--    Get out templates
        //--	--------------------------------------------------------------------
        objTemplate_email = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Initial];
        FOR(EmailTemplate thistemplate_email: objTemplate_email)
        {
            template_email_id = thisTemplate_email.id;
            SYSTEM.debug(thisScript + 'Initial Template: ' + thisTemplate_email.Name);
        }

        objTemplate_password = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Password];
        FOR(EmailTemplate thistemplate_password: objTemplate_password)
        {
            template_password_id = thistemplate_password.id;
            SYSTEM.debug(thisScript + 'Password Template: ' + thistemplate_password.Name);
        }

        
        //--    Loop through the objMailout list and create the emails to be sent
        //--	--------------------------------------------------------------------
        FOR (ci_mailout__c thisMailOut: objMailout) 
        {
        	SYSTEM.debug(thisScript + 'Looping through the mailout data');
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setTargetObjectId(thisMailOut.contact__c);
            email.setTemplateId(template_email_id);
            email.setSaveAsActivity( TRUE );
            email.setToAddresses(new String[] { thisMailout.email_address__c });
            email.setTreatTargetObjectAsRecipient(FALSE);
            email.setUseSignature(FALSE);
            email.setWhatId(thisMailout.Id);
            email.setOrgWideEmailAddressId(strEmailFrom);

			//--    Get the Email Attachment
			//--	------------------------
            SYSTEM.debug(thisScript + 'No Attachments: ' + objAttachment.size());
            IF( mName.keySet().contains(thisMailout.Id) )
            {
                SYSTEM.debug(thisScript + 'Looping through Attachment');
                Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
                efa.setFileName( mName.get(thisMailout.Id));
                efa.setBody( mBody.get( thisMailout.Id ));
                efa.setContentType( mContentType.get( thisMailout.Id ));
                email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
            }

            //--	Add the email to the msgList for sending & keep track of the totalSend
            //--	----------------------------------------------------------------------------
            msgList.add(email);
            iCountTotalSend++;

            //--	Check and add the attachment if we need too
            //--	------------------------------------------------------------
            SYSTEM.debug(thisScript + 'Check if we have a password template');
            IF ( objTemplate_password.size() > 0 )
            {
                SYSTEM.debug(thisScript + 'Creating Password Email');
                Messaging.SingleEmailMessage email_pass = new Messaging.SingleEmailMessage();
                email_pass.setToAddresses(new String[] { thisMailout.email_address__c });
                email_pass.setTreatTargetObjectAsRecipient(FALSE);
                email_pass.setTargetObjectId(thisMailOut.contact__c);
                email_pass.setTemplateId(template_password_id);
                email_pass.setSaveAsActivity( TRUE );
                email_pass.setUseSignature( FALSE );
                email_pass.setOrgWideEmailAddressId(strEmailFrom);
                email_pass.setWhatId(thisMailout.Id);

                //--	Add the email to the msgList for sending & keep track of the totalSend
                //--	----------------------------------------------------------------------------
                msgList.add(email_pass);
                iCountTotalSend++;
            }

            //--	Now that we have created the email to be sent, let us update the details of the mailout so we can track once it is actuall sent
            //--	--------------------------------------------------------------------------------------------------------------------------------
            thisMailout.Sent__C = TRUE;
            thisMailout.Sent_Date__c = SYSTEM.now();
            updateMailout.add( thisMailout );

            //--	Check to see if we need to send a batch out because we are at the end
            //--	------------------------------------------------------------------------
            SYSTEM.DEBUG(thisScript + 'Message List size: ' + msgList.size());
            IF( msgList.size() == iBatchSize || objMailout.size() == iCountTotalSend )
            {
                List<Messaging.SendEmailResult> results = Messaging.sendEmail( msgList, false );
                IF(!results.get(0).isSuccess())
                {
                    SYSTEM.DEBUG(thisScript + 'This was unsuccessful: ' + results[0].getErrors().get(0).getMessage());
                    BREAK;
                }
                ELSE
                {
                    SYSTEM.DEBUG( thisScript + 'We have successfully sent a batch of emails. ' + iCountTotalSend + ' of ' + objMailout.size() );
                    msgList.clear();
    
                    //--	Now that we have update the send list so we don't send out again
                    //--	------------------------------------------------------------------------------------------------
                    TRY{ update updateMailout; }
                    CATCH ( Exception ex )
                    {	 SYSTEM.DEBUG(thisScript + 'Could not update the Mailout. Cause: ' + ex.getCause() );	updateMailout.clear();	}
                }
            }	//--	End Sending out the batches	
        }	//--	End Looping throught objMailout
    }	//--	End send_mailout

 
I am trying to get back a count of records in the task / event object for contacts so that I can update a contact field with the correct vale of activity.

I am passing a LIST<ID> to the function. The trouble appears on the highlighted lines below
LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs];
LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs];

The Error I get is:
Field must be grouped or aggregated: WhoId

But if I try and group it, it gives me errors as well
LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs GROUP BY WHOID];
LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs GROUP BY WHOID];
This gives the error
Illegal assignment from List<AggregateResult> to List<Task>


 

The Function
PUBLIC VOID updateActivityCount( LIST<ID> listContacts )
	{
        LIST<ID> ContactIDs = NEW LIST<ID>();
		ContactIDs = listContacts;

		INTEGER tmpTasks = 0;
		INTEGER tmpEvents = 0;

		
		LIST<CONTACT> contactUpdate = NEW LIST<CONTACT>();
		MAP<ID, INTEGER> contactTasks = NEW MAP<ID, INTEGER>();
		MAP<ID, INTEGER> contactEvents = NEW MAP<ID, INTEGER>();

        LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs];
        LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs];

		FOR(TASK thisTask : objTasks)
		{	contactTasks.put(thisTask[0], thisTask[1]);	}

		FOR(EVENT thisEvent : objEvents)
		{	contactEvents.put(thisEvent[0], thisEvent[1]);	}

		LIST<CONTACT> objContacts = [SELECT ID FROM Contact WHERE ID IN :ContactIDs];
		FOR(CONTACT thisContact : objContacts)
		{
			IF( contactTasks.containsKey( thisContact.Id ) )
			{	tmpTasks = contactTasks.get( thisContact.Id );	}
			ELSE
			{	tmpTasks = 0;	}

			IF( contactEvents.containsKey( thisContact.Id ) )
			{	tmpTasks = contactEvents.get( thisContact.Id );	}
			ELSE
			{	tmpEvents = 0;	}

			thisContact.activity_this_cfy__c = tmpTasks + tmpEvents;
			contactUpdate.add( thisContact );
		}

		//--    Execute the update for contactUpdate
		//------------------------------------------------------------------------------------------------------------------------------
		if ( !contactUpdate.isEmpty() )
		{
			TRY{ update contactUpdate; }
			CATCH ( Exception ex )
			{   SYSTEM.DEBUG(thisPage + 'Could not update Contact. Cause: ' + ex.getCause() );  }
		}
	}	//--	END updateActivityCount


 
Hi

Iam attempting to reduce the number of SOQL's being triggered to avoid the limits.

I currently have two queiries. The first brings back the mailout items and the second brings back the attachements for the mailout items

Get the mailout items
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];
Get the attachments for the above mailout items
objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];
So ... the above works but gets close to the limit for SOQL

So when I try to join the SOQL into 1 I get the following error
A driving SObject type has already been set, all other entity types in the FROM clause must be relationships to the initial object.  The driving object is CI_Mailout__c.
This is the query that I am attempting to use
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c, attachment WHERE ID = :[SELECT PARENTID FROM ATTACHMENT] AND Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];

Any guidance would be greatly appreciated.

Thanks


 
I ma trying to get the reply-to field in a visualforce email. My hope is to be able to call a class function which I have that will check the value I pass to it and add the email address accordingly.
 
<messaging:emailTemplate subject="Product Upgrade Boardroom Session"
    recipientType="Contact"
    relatedToType="CampaignMember"
    replyTo="DYNAMCIALLY CHANGE VIA CALL TO CLASS FUNCTION (ci_class.emailFromAddress(passedValue)">
 
PUBLIC STRING emailFromAddress ( STRING strSender )
	{
		STRING strEMail = NULL;
		//--	Set the mapping for the Sender / Email
		//--	--------------------------------------------------------------------------------------------------------
		MAP<STRING, STRING> senderMap = NEW MAP<STRING, STRING>();	//--	Stores Key Value Pairs
		senderMap.put('Sales NSW/ACT', 'nswactsales@yy.com.au');
		senderMap.put('Sales QLD', 'qldsales@yy.com.au');
        senderMap.put('Sales VIC/TAS', 'victassales@yy.com.au');
        senderMap.put('Sales WA/SA/NT', 'wastatesales@yy.com.au');
		senderMap.put('National', 'xx@yy.com.au');

		IF( senderMap.containsKey( strSender ) )
		{
			strEmail = senderMap.get( strSender );
			RETURN strEmail;
		}
		ELSE
		{	RETURN strEMail;	}
		
	}

Was thinking of calling a component but it doesn't allow me to call that inside the message tags.

Any thoughts??



 
I am attempting to create a trigger that will update certain fields if the value in a multipicklist is present.

Rather than have 20 If statements to check if the value is in it, I want to be able to something like 

IF taskListValue is in picklistValue
THEN fieldToUpdate = fieldListValue.indexof( taskListValue.indexof( picklistValue )

It would then say something like ...

thisRecord.fieldToUpdate = TRUE

updateObject.add(thisRecord);

What I currently have is
 
//-- Some Varaibles to start with

STRING strRelated = thisTask.Campaign_Related__c;
STRING[] strRelated_split = strRelated.split(';');

LIST<STRING> lstOfTasks = NEW LIST<STRING>(); //-- Stores the values that can be in the multipicklist thisTask.Campaign_Related__c
LIST<STRING> lstOfFields = NEW LIST<STRING>(); //-- Stores the field names that we want to update if the values is passed. These are in the same sequence so getting the index of one will refer to the index of the other.

//-- Add some values to our lists
lstOfTasks.add('EDU - Business Insurance Session');
lstOfFields.add('Business_Insurance_Session_Completed__c');
lstOfTasks.add('EDU - CBA/CFP Branch Training Session');
lstOfFields.add('CBA_CFP_Branch_Training_Session_Complete__c');
lstOfTasks.add('EDU - Client Seminars');
lstOfFields.add('Client_Seminars_Completed__c');


FOR(intCount = 0; intCount < strRelated_split.size() ; intCount++)
{
    IF( strReleated_split[intCount] is in lstOfTasks)
    {
        intX = lstOfTasks.indexOf( strReleated_split[intCount] );
        theField = lstOfFields[intX]
        thisAMP.thisField = TRUE;
    }
}
Any help would be appreciated.
 
Hi have a class that I am using to return dynamic information to the visualforce page. The error is happening at 
 
IF( MONTH( Date.today() ) == 5 )

Full Code
PUBLIC STRING getButton()
    {
        IF( MONTH( Date.today() ) == 5 )
        {
            theButton = 'Show: ';
            RETURN theButton;
        }
        ELSE
        {
            theButton = 'dont show';
            RETURN theButton;
        }
        RETURN null;
    }



 
I am getting the following error whe I attempt to execute a query.
 
Line: 4, Column: 14
Didn't understand relationship 'attachment' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.
The query (being executed via the debug in developer console
PUBLIC STRING strTemplate_Initial;
strTemplate_Initial = 'TEST EMAIL';

PUBLIC LIST <ci_mailout__c> objMailout;

objMailout = [SELECT m.Id, m.contact__c, contact__r.Name, m.recipient_first_name__c, m.recipient_last_name__c, caps__r.AccountID__c, m.file_password__c, m.email_address__c, (SELECT ID, Name, ContentType, body FROM attachment) FROM ci_mailout__c m WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 100];

SYSTEM.debug('Size of Mailout: ' + objMailout.size());

The code I originally had was two seperate queries on for the mailout and one for attachements which worked, however, it starts to hit the limit for SOQL statements and so I was thinking I could join the two statements to reduce the calls.

Original SOQL (in isolation)
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];

objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];

Thanks for your help ...



 
I have an issue where I am sending out SingleEmailMessage on mass using a visualforce enail template. Some of the information is in a custom object c0_mailout__c which I have in the email template as the relatedtotype. When I execite the script to test it, the email that I receive doesn't have the related details I am after (ci_mailout__c.file_password__c, ci_mailout_file_name__c). In debugging, I note that the relatedto ID doesn't appear to be present when the email is generated.

Based on this, I believe that my script isn't passing the relatedto information that the template requires. Is there a way using SingleEmailMessage to pass the relatedtoid to the email template?

Apex Class CI_Mailout
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//--
//--	Name:
//--	CI_MailOut
//--
//--	Purpose:
//--	Used in conjunction with CI_Mailout__c
//--
//--	Created by:
//--	Andrew Telford
//--
//--	Date:
//--	2016-06-02
//--
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------

PUBLIC class CI_MailOut {

	PUBLIC CI_Mailout() {}

	PUBLIC ID mailoutID { get; set; }
	PUBLIC ID contactID { get; set; }
	PUBLIC LIST<CI_MAILOUT__C> objPasswords{ get; set; }

    PUBLIC LIST <ci_mailout__c> objMailout;
	PUBLIC LIST <attachment> objAttachment;
	PUBLIC LIST <Messaging.SingleEmailMessage> msgList = new List <Messaging.SingleEmailMessage> ();
	PUBLIC LIST <CI_MAILOUT__C> updateMailout = NEW LIST<CI_MAILOUT__C>();
	PUBLIC LIST <EmailTemplate> objtemplate_email;
	PUBLIC LIST <EmailTemplate> objtemplate_password;

    PUBLIC STRING strTemplate_Initial;
	PUBLIC STRING strTemplate_Password;
	PUBLIC STRING strEmailFrom;
	PUBLIC STRING template_email_id;
	PUBLIC STRING template_password_id;

    STRING thisScript = 'CI_Mailout.apxc: ';

	//------------------------------------------------------------------------------------------------------
	//
	//--	get_mail_attachment
	//--
	//--	Use:
	//--	This is used as a component for visual force emails generated from ci_mailout__c
	//
	//------------------------------------------------------------------------------------------------------
	PUBLIC LIST<attachment> get_mail_attachment()
	{
		LIST<attachment> objAttachments;
		objAttachments = [SELECT ID FROM Attachment WHERE ParentID = :mailoutID];
		RETURN objAttachments;
	}

	PUBLIC LIST<CI_MAILOUT__C> getPassword()
	{
		objPasswords = [SELECT recipient_first_name__c, recipient_last_name__c, File_Name__c, File_Password__c FROM CI_MAILOUT__C WHERE ID = :mailoutID];
        SYSTEM.DEBUG(thisScript + 'getPassword - objPasswords size: ' + objPasswords.size());
		RETURN objPasswords;
	}

	//------------------------------------------------------------------------------------------------------
	//--
	//--	send_mailout
	//--
	//--	Use:
	//--	This is the process to actually send the email and will be triggered by a scheduled APEX
	//--
	//--
	//------------------------------------------------------------------------------------------------------
	PUBLIC VOID send_mailout(STRING mailOutName)
	{
		//--	Our variables
		BOOLEAN sndSuccess = FALSE;
		
		strTemplate_Initial = mailOutName;
		strTemplate_Password = mailOutName + ' - Password';

		//--	Set the FROM email address
		for(OrgWideEmailAddress owa : [select id, Address, DisplayName from OrgWideEmailAddress]) 
		{
			strEmailFrom = owa.id;
		} 

		//--	Get the details of who we are going to send to
		objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 500];
		SYSTEM.debug(thisScript + 'Size of Mailout: ' + objMailout.size());

		//--	Get the Mailtemplate that we are going to use
		objTemplate_email = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Initial];
		FOR(EmailTemplate thistemplate_email: objTemplate_email)
		{
			template_email_id = thisTemplate_email.id;
			SYSTEM.debug(thisScript + 'Initial Template: ' + thisTemplate_email.Name);
		}

		objTemplate_password = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Password];
		FOR(EmailTemplate thistemplate_password: objTemplate_password)
		{
			template_password_id = thistemplate_password.id;
			SYSTEM.debug(thisScript + 'Password Template: ' + thistemplate_password.Name);
		}

		FOR (ci_mailout__c thisMailOut: objMailout) {
		SYSTEM.debug(thisScript + 'Looping through the mailout data');
			Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
			email.setTargetObjectId(thisMailOut.contact__c);
			email.setTemplateId(template_email_id);
			email.setSaveAsActivity(true);
			email.setToAddresses(new String[] { thisMailout.email_address__c });
			email.setTreatTargetObjectAsRecipient(FALSE);
			email.setUseSignature(FALSE);
			email.setOrgWideEmailAddressId(strEmailFrom);

		//--	Get the Email Attachment
			objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];
			SYSTEM.debug(thisScript + 'No Attachments: ' + objAttachment.size());
			if( objAttachment.size() > 0)
			{
				FOR(attachment thisAttachment: objAttachment)
				{
					SYSTEM.debug(thisScript + 'Looping through Attachment');
					Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
					efa.setFileName(thisAttachment.Name);
					efa.setBody(thisAttachment.body);
					efa.setContentType(thisAttachment.ContentType);
					email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
				}
			}

			msgList.add(email);

			SYSTEM.debug(thisScript + 'Check if we have a password template');
			IF ( objTemplate_password.size() > 0 )
			{
				SYSTEM.debug(thisScript + 'Creating Password Email');
				Messaging.SingleEmailMessage email_pass = new Messaging.SingleEmailMessage();
				email_pass.setToAddresses(new String[] { thisMailout.email_address__c });
				email_pass.setTreatTargetObjectAsRecipient(FALSE);
				email_pass.setTargetObjectId(thisMailOut.contact__c);
				email_pass.setTemplateId(template_password_id);
				email_pass.setSaveAsActivity(true);
				email_pass.setUseSignature(FALSE);
				email_pass.setOrgWideEmailAddressId(strEmailFrom);
				msgList.add(email_pass);
			}
		}

		SYSTEM.DEBUG(thisScript + 'Message List size: ' + msgList.size());
		IF( msgList.size() > 0 )
		{
			List<Messaging.SendEmailResult> results = Messaging.sendEmail( msgList, false );
			IF(!results.get(0).isSuccess())
			{
   				SYSTEM.DEBUG(thisScript + 'This was unsuccessful: ' + results[0].getErrors().get(0).getMessage());
			}
			ELSE
			{
   				FOR( CI_MAILOUT__C thisMailout: objMailOut)
				{
					thisMailout.Sent__C = TRUE;
					thisMailout.Sent_Date__c = SYSTEM.now();
					updateMailout.add( thisMailout );
				}

				IF( !updateMailout.isEmpty() )
				{
					update updateMailout;
				}
			}
			System.debug(thisScript +  results );
		}
	}
}



VisualForce Component ci_mailout_password
<apex:component controller="CI_MailOut" access="global">
    <apex:attribute name="mailID"
        type="Id"
        description="Mailout Reference"
        assignTo="{!mailoutID}" />

        <apex:repeat value="{!Password}" var="p">

            <p>Dear {!p.Recipient_First_Name__c}</p>
            <p>Here is your password to access your CommInsure client list. These clients will shortly receive information about CommInsure’s enhancement to medical definitions.</p>
            <ul>
                <li>File Name: {!p.File_Name__c} </li>
                <li>Password: {!p.File_Password__c}</li>
            </ul>
        </apex:repeat>
</apex:component>



Visualforce Email Template
<messaging:emailTemplate subject="File password for enhancement of medical definitions communications to CommInsure clients" recipientType="Contact" relatedToType="CI_Mailout__c" replyTo="">

    <messaging:HtmlEmailBody >
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                <meta name="format-detection" content="telephone=no" />
                <meta name="format-detection" content="date=no" />
                <meta name="format-detection" content="address=no" />
                <meta name="format-detection" content="time=no" />
                <c:ci_email_style_sheet />
            </head>
            <body style="-moz-osx-font-smoothing: grayscale; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: none; -webkit-touch-callout: none; margin: 0px; padding: 0px; width: 100% !important">



<!--    Email Header - End  -->

<!--    Email Content   -->
                                                                                        <h3>File password for enhancement of medical definitions communications to CommInsure clients</h3>
<p>Related to: {!RelatedTo.Id}</p><!-- DEBUG-->
<p>Related Name: {!relatedTo.Name}</p><!-- DEBUG-->

<c:CI_MailOut_Password mailID="{!relatedTo.id}" />
<p>If you have any questions, please contact your Business Development Manager.</p>

<!--    Email Content - End -->

<!--    Email Signature -->
<c:ci_email_signature />
<p>&nbsp;</p>
<p>&nbsp;</p>

<!--    Email Footer    -->

            </body>
        </html>
    </messaging:HtmlEmailBody>
</messaging:emailTemplate>

 
Hi

I have a custom object ci_mailout and it has a picklist filed called mailout_name__c. When I create the following query, it tells me that there is an unexpected ';'. From what I can see there isn't anything unexpected. Is it something to do with the picklist??
 
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE, Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 250];

note that objMailout has been declared earlier (PUBLIC LIST <ci_mailout__c> objMailout;) in the script.
I am attempting to use a frame work (http://chrisaldridge.com/triggers/lightweight-apex-trigger-framework/) and I am running in to an issue when I attempt to loop thorugh a MAP that is passed to a class.

This is the code I currently have
public void AfterInsert( Map<Id, SObject> newItems )
{
//– Collect the common information
//———————————————————————————————————————-
List<Contact> contsToUpdate = new List<Contact>();
List<Contact> updateContacts = new List<Contact>();
Set<<D> contactIDs = new Set<ID>();
List<Task> thisTask = new List<Task>();

SYSTEM.debug('Where Are We?: AfterInsert Task');
SYSTEM.debug('What type of object?: ' + newItems.getSObjectType() );
SYSTEM.debug('What is our Size: ' + newItems.size() );
SYSTEM.debug('Who?: ' + newItems.get('WhoId') );

Map<Id, Task> MyMap = new Map<Id, Task>(newItems); //– Error here 
thisTask.addAll(MyMap.values());
}

This is the error I get when I save the TaskTriggerHandler class
Invalid initial type Map<Id,SObject> for Map<Id,Task>

What am I missing?.
 
Hi

I am trying to reference a particular record in a recordset that has been returned from an SOQL statement. I am doing this as part of a test class and I am not concerned which record I return but I do need to return the second record in another section of the script.
User rsUsers = [ SELECT Id, Username, Email, Alias, CommunityNickname, TimeZoneSidKey, LocaleSidKey, EmailEncodingKey, ProfileId, LanguageLocaleKey FROM user WHERE name = 'State Account' or name = 'Andrew Telford' ];
I have been trying do this by doing
 
Contact srvContact = new Contact
			( 
				AccountID = acct.Id,
				FirstName = 'John',
				LastName = 'Smith',
				OwnerID = rsUsers[0].Id,
				RecordTypeId = recType.Id,
				Approved_Owner_Change__c = FALSE,
				Approved_Owner_Name__c = NULL,
				CCC_Adviser__c = FALSE,
				Segmentation_Tier__c = 'Tier 4'
			);
			insert srvContact;
Any assistance or direction would be appreciated.

 
Hi

I am getting the above error but can't seem to locate exactly what the issue is. A few other posts suggest that I need to remove the DML from within the For loops. I believe I have done this unless I am missing something.

Can the community assist me in this please?
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-07-31
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Contact on Contact ( after insert, after update, after delete, after undelete) 
{

//  Let us prepare some common variables
//----------------------------------------------------------------------------------------------
    system.debug('Set the variables');

    // Common items
    STRING thisContactID;
    STRING thisContactOwnerID;
    STRING userID;
    STRING userProfileID;
    STRING errMsg = '';


//--    Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
    system.debug('Contact[]');

//--    Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
    Contact[] strContact;

    if (Trigger.isDelete) 
    {   strContact = Trigger.old;   }
    else
    {   strContact = Trigger.new;   }

    Set<ID> contactID = new Set<ID>();
	Set<ID> ownerIds = new Set<ID>();
	Set<ID> oldOwnerIds = new Set<ID>();
    for(Contact objCont: strContact)
    {
        ownerIds.add(objCont.ownerId);
        if ( !TRIGGER.isInsert && !TRIGGER.isunDelete )
        {	
            oldOwnerIds.add(TRIGGER.oldMap.get(objCont.Id).ownerId);
        }
    }


    LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :strContact AND Approved_Owner_Change__c = TRUE];
    LIST<User> thisOwner = [Select Id FROM User WHERE ID IN :ownerIds];
	LIST<Contact> ownerMMCount = [SELECT Id FROM Contact WHERE ownerId IN :ownerIds AND CCC_Adviser__c = TRUE];
    LIST<User> oldOwner = [Select Id FROM User WHERE ID IN :oldOwnerIds];
    LIST<Contact> oldOwnerMMCount = [SELECT Id FROM Contact WHERE ownerId IN :oldOwnerIds AND CCC_Adviser__c = TRUE];

    FOR(Contact objCont: strContact)
    {
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Owner Change Approved
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

        system.debug('Set the variable values');

    //--    Define any variables required
    //----------------------------------------------------------------------------------------------
        BOOLEAN approvedOwnerChange;
        STRING newContactID = '';

    //--    Assign Values to Variables
    //----------------------------------------------------------------------------------------------
        contactID.add(objCont.Id);
        thisContactID = objCont.Id;
        thisContactOwnerID = objCont.OwnerId;
        userID = userinfo.getUserId();
        userProfileID = userinfo.getProfileId();
        approvedOwnerChange = objCont.Approved_Owner_Change__c;

        system.debug('Determine if owner is to change');

    //--    Check for change forced by workflow
    //----------------------------------------------------------------------------------------------

		if ( !TRIGGER.isAfter && !TRIGGER.isDelete )
        {
            if( objCont.Approved_Owner_Change__c )
            {

    //--    Check to see if we are updating the owner
    //----------------------------------------------------------------------------------------------
                if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
                {
					system.debug('Owner is to change');

    //--    Set the update list
    //----------------------------------------------------------------------------------------------
	                List<Contact> updateOwner = new List<Contact>();

                    FOR (Contact cont: contsToUpdate)
                    {
	                    Boolean alterOwner = FALSE;

                        IF ( cont.Approved_Owner_Change__c = TRUE )
                        {   alterOwner  = TRUE; }

                        if (alterOwner) 
                        {
                            cont.OwnerID = cont.Approved_Owner_Name__c;
                            cont.Approved_Owner_Change__c = FALSE;
                            newContactID = cont.Approved_Owner_Name__c;
                        }
                        updateOwner.add(cont);
                    }


    //--    Execute the update
    //----------------------------------------------------------------------------------------------
                    if (!updateOwner.isEmpty()) 
                    {
                        try{ update updateOwner; }
                        catch (Exception ex)
                        { System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
                    }
                }
            }   //--    End Check for automated change after insert
        }
//
//  End Approve Owner Change
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
//
//  Magic Movers
//
//  This works in conjunction with:
//      Validations
//          Magic Mover Addition (03dc00000009014)
//          Magic Mover REmoval (03dc00000009080)
//
//      Workflow Field Update
//          New Contact (01Q20000000Es9Z)
//          Set Magic Mover to False (04Yc000000090G1)
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

    //--    Magic Movers 
        BOOLEAN magicMover;
        DECIMAL userMagicCount;

    //--    Select the Owner Information
        LIST<User> updateMM = new LIST<User>();
        system.debug( 'Size of thisUser: ' + thisOwner.size());

		FOR ( User mm1: thisOwner )
        {
            mm1.Magic_Movers_Count__c = ownerMMCount.size();
            updateMM.add(mm1);

        }   //--    For Current Owner Loop

    //--    Process the updates
    //------------------------------------------------------------------------------------------------------------------------------
        system.debug('size of: ' + updateMM.size());
        if (!updateMM.isEmpty()) 
        {
            try{ update updateMM; }
            catch (Exception ex)
            { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
        }

	//--	Check to see if the Owner has changed
	//-----------------------------------------------------------------------------------------------------------------------------
        LIST<User> updateOldMM = new LIST<User>();
        system.debug( 'Size of oldOwner: ' + oldOwner.size());

		FOR ( User mm2: oldOwner )
        {
            mm2.Magic_Movers_Count__c = oldOwnerMMCount.size();
            updateOldMM.add(mm2);

        }   //--    End For Old Owner Loop

	//--    Process the updates
    //------------------------------------------------------------------------------------------------------------------------------
        system.debug('size of: ' + updateOldMM.size());
        if (!updateOldMM.isEmpty()) 
        {
            try{ update updateOldMM; }
            catch (Exception ex)
            { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
        }


//
//  End Magic Movers
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

    }
//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}

 
Hi

I am trying to get a trigger based on Contact to funciton but I am continually getting an error relating to too many SOQL Queries. The error states I am getting the error on Line 60.

Should I create a 2nd Contact Trigger file and have it only execute AFTER update?
LIST<Contact> thisCount = [SELECT Id FROM Contact WHERE OwnerId IN :ownerIds AND CCC_Adviser__c = TRUE];
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Trigger_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-08-17
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Trigger_Contact on Contact ( after insert, after update, before update, after delete, after undelete) 
{

//	Let us prepare some common variables
//----------------------------------------------------------------------------------------------
system.debug('Set the variables');

	// Common items
	STRING thisContactID;
	STRING thisContactOwnerID;
	STRING userID;
	STRING userProfileID;
	STRING errMsg = '';


//--	Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
system.debug('Contact[]');

//--	Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
	Contact[] strContact;

	if (Trigger.isDelete) 
	{	strContact = Trigger.old;	}
	else
	{	strContact = Trigger.new;	}

	Set<ID> contactID = new Set<ID>();
	Set<ID> ownerIds = new Set<ID>();
	for(Contact objCont: strContact)
	{	ownerIds.add(objCont.ownerId);	}

    //--	For Owner Change Approved
	//----------------------------------------------------------------------------------------------
	LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :strContact AND Approved_Owner_Change__c = TRUE];

    //--	For Magic Movers
	//----------------------------------------------------------------------------------------------
    LIST<User> thisOwner = [Select Id FROM User WHERE ID IN :ownerIds];
//-- Line 60 is below
    LIST<Contact> thisCount = [SELECT Id FROM Contact WHERE OwnerId IN :ownerIds AND CCC_Adviser__c = TRUE];

	FOR(Contact objCont: strContact)
	{

	//----------------------------------------------------------------------------------------------
	//----------------------------------------------------------------------------------------------
	//
	//  Owner Change Approved
	//
	//
	//

	//--	Define any variables required
	//----------------------------------------------------------------------------------------------
		system.debug('Set the variable values');
		BOOLEAN approvedOwnerChange;
		STRING newContactID = '';

	//--	Assign Values to Variables
	//----------------------------------------------------------------------------------------------
		contactID.add(objCont.Id);
		thisContactID = objCont.Id;
		thisContactOwnerID = objCont.OwnerId;
		userID = userinfo.getUserId();
		userProfileID = userinfo.getProfileId();
		approvedOwnerChange = objCont.Approved_Owner_Change__c;


	//--	Check to see if we are updating the owner
	//----------------------------------------------------------------------------------------------
		system.debug('Owner is to change');
		if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
		{

	//--	Set the update list
	//----------------------------------------------------------------------------------------------
			List<Contact> updateOwner = new List<Contact>();

			FOR (Contact cont: contsToUpdate)
			{
				Boolean alterOwner = FALSE;

				IF ( cont.Approved_Owner_Change__c )
				{
					cont.OwnerID = cont.Approved_Owner_Name__c;
					cont.Approved_Owner_Change__c = FALSE;
					newContactID = cont.Approved_Owner_Name__c;
					updateOwner.add(cont);
				}
			}


	//--	Execute the update
	//----------------------------------------------------------------------------------------------
			if (!updateOwner.isEmpty()) 
			{
				try{ update updateOwner; }
				catch (Exception ex)
				{ System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
			}
		}

	//
	//  End Approve Owner Change
	//
	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------


	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------
	//
	//  Magic Movers
	//
	//	This works in conjunction with:
	//		Validations
	//			Magic Mover Addition (03dc00000009014)
	//			Magic Mover REmoval (03dc00000009080)
	//
	//		Workflow Field Update
	//			New Contact (01Q20000000Es9Z)
	//			Set Magic Mover to False (04Yc000000090G1)
	//
	//
	//

	//--	Magic Movers 
	//------------------------------------------------------------------------------------------------------------------------------
		IF ( TRIGGER.isAfter )
        {
            BOOLEAN magicMover;
			DECIMAL userMagicCount;

	//--	Select the Owner Information
	//------------------------------------------------------------------------------------------------------------------------------
            system.debug( 'Size of thisUser: ' + thisOwner.size());
            LIST<User> updateUser = new LIST<User>();

            for ( User o1: thisOwner )
            {
                o1.Magic_Movers_Count__c = thisCount.size();
                updateUser.Add(o1);

            }	//--	For Owner Loop
	//--	Process the updates
	//------------------------------------------------------------------------------------------------------------------------------
                system.debug('size of: ' + updateuser.size());
                if (!updateUser.isEmpty()) 
                {
                    try{ update updateUser; }
                    catch (Exception ex)
                    { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
                }
        }	//--	End Check for After          

	//
	//  End Magic Movers
	//
	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------
		//objCont.addError(errMsg);
	}

//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}

 
Hi

I have the following trigger that appears to be ok in the sandbox and in production it all validates. I tried to insert some contacts today using Apex Data Loader and got the error relating to too many SOQL queries.

I thought I had bulkified it but evidently this isn't the case. Can some one assist in pointing me in the right direction as to where I have gone wrong please.

Thanks
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Trigger_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-07-31
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Trigger_Contact on Contact ( after insert, after update, after delete, after undelete) 
{

//	Let us prepare some common variables
//----------------------------------------------------------------------------------------------
	system.debug('Set the variables');

	// Common items
	STRING thisContactID;
	STRING thisContactOwnerID;
	STRING userID;
	STRING userProfileID;
	STRING errMsg = '';


//--	Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
	system.debug('Contact[]');

//--	Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
	Contact[] strContact;

	if (Trigger.isDelete) 
	{	strContact = Trigger.old;	}
	else
	{	strContact = Trigger.new;	}

	Set<ID> contactID = new Set<ID>();
	FOR(Contact objCont: strContact)
	{
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Owner Change Approved
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

		system.debug('Set the variable values');

	//--	Define any variables required
	//----------------------------------------------------------------------------------------------
		BOOLEAN approvedOwnerChange;
		STRING newContactID = '';

	//--	Assign Values to Variables
	//----------------------------------------------------------------------------------------------
		contactID.add(objCont.Id);
		thisContactID = objCont.Id;
		thisContactOwnerID = objCont.OwnerId;
		userID = userinfo.getUserId();
		userProfileID = userinfo.getProfileId();
		approvedOwnerChange = objCont.Approved_Owner_Change__c;

		system.debug('Determine if owner is to change');

	//--	Check for change forced by workflow
	//----------------------------------------------------------------------------------------------
		if( !objCont.Approved_Owner_Change__c && ( TRIGGER.newMap.get( objCont.Id ).OwnerId != '00520000000noZtAAI' || TRIGGER.newMap.get( objCont.Id ).OwnerId != '00520000000noZtAAI' ) )
		{

	//--	Check to see if we are updating the owner
	//----------------------------------------------------------------------------------------------
			if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
			{
				system.debug('Owner is to change');
				LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :contactID AND Approved_Owner_Change__c = TRUE];

	//--	Set the update list
	//----------------------------------------------------------------------------------------------
				List<Contact> updateOwner = new List<Contact>();

				FOR (Contact cont: contsToUpdate)
				{
					Boolean alterOwner = FALSE;

					IF ( cont.Approved_Owner_Change__c = TRUE )
					{	alterOwner  = TRUE;	}

					if (alterOwner) 
					{
						cont.OwnerID = cont.Approved_Owner_Name__c;
						cont.Approved_Owner_Change__c = FALSE;
						newContactID = cont.Approved_Owner_Name__c;
						updateOwner.add(cont);
					}
				}


	//--	Execute the update
	//----------------------------------------------------------------------------------------------
				if (!updateOwner.isEmpty()) 
				{
					try{ update updateOwner; }
					catch (Exception ex)
					{ System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
				}
			}
		}	//--	End Check for automated change after insert



//
//  End Approve Owner Change
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
//
//  Magic Movers
//
//	This works in conjunction with:
//		Validations
//			Magic Mover Addition (03dc00000009014)
//			Magic Mover REmoval (03dc00000009080)
//
//		Workflow Field Update
//			New Contact (01Q20000000Es9Z)
//			Set Magic Mover to False (04Yc000000090G1)
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

	//--	Magic Movers 
		BOOLEAN magicMover;
		DECIMAL userMagicCount;

	//--	Select the Owner Information
		LIST<User> thisOwner = [Select Magic_Movers_Count__c FROM User WHERE ID = :objCont.OwnerID];
		LIST<User> updateUser = new LIST<User>();
		system.debug( 'Size of thisUser: ' + thisOwner.size());

		for ( User o1: thisOwner )
		{
			if( o1.Magic_Movers_Count__C == NULL )
			{ userMagicCount = 0; }
			else
			{ userMagicCount = o1.Magic_Movers_Count__C; }
            system.debug('No. of Magic Movers = ' + userMagicCount);

            if( !TRIGGER.isinsert && !TRIGGER.isUnDelete )
            {
                
	//--	Has Magic Mover been altered?
	//------------------------------------------------------------------------------------------------------------------------------
                if( objCont.CCC_Adviser__c != TRIGGER.oldMap.get( objCont.Id ).CCC_Adviser__c 
                    && TRIGGER.isupdate && thisContactOwnerID == userID )
                {
	//--	Check to see if the owner has the magic count limit and the change is an addition
	//------------------------------------------------------------------------------------------------------------------------------
                    if( userMagicCount < 21 && objCont.CCC_Adviser__c )
                    {
                        o1.Magic_Movers_Count__c = userMagicCount + 1;
                        updateUser.add(o1);
                        system.debug('size of: ' + updateuser.size());
                    }
                    else if ( !objCont.CCC_Adviser__c )
                    {
                        o1.Magic_Movers_Count__c = userMagicCount - 1;
                        updateUser.add(o1);
                        system.debug('size of: ' + updateuser.size());
                    }
                }
			//--	End check for change in Magic Mover

	//--	Reduce the count when the owner is changed
	//------------------------------------------------------------------------------------------------------------------------------
                else if ( TRIGGER.isUpdate && TRIGGER.isBefore && objCont.OwnerId != TRIGGER.oldMap.get( objCont.Id ).OwnerId )
                { objCont.CCC_Adviser__c = FALSE; }

	//--	When the contact is deleted, reduce the count
	//------------------------------------------------------------------------------------------------------------------------------
                else if ( TRIGGER.isDelete )
                {
                    o1.Magic_Movers_Count__c = userMagicCount - 1;
                    updateUser.add(o1);
                    system.debug('size of: ' + updateuser.size());
                }
                //--	End check for delete
            }

	//--	Process the updates
	//------------------------------------------------------------------------------------------------------------------------------
            system.debug('size of: ' + updateuser.size());
			if (!updateUser.isEmpty()) 
			{
				try{ update updateUser; }
				catch (Exception ex)
				{ objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
			}
		}	//--	For Owner Loop

//
//  End Magic Movers
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

	}
//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}

 
Hi

I am getting the following error when I am in the developer console and if I attempt to trigger the process on the contact layout.
 
Method does not exist or incorrect signature: [List<Contact>].addError(String)

What I am trying to do is return a message as an error to the contact screen in the event that the number of contacts meeting a specific criteria is exceeded.

 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_MagicMover
//
//  Purpose:
//      This is a script to ensure that the user only has a certain number of contacts listed 
//      as a Magic Mover
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-07-22
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_MagicMover on Contact (before update) {
    Contact[] sContact;

    sContact = Trigger.new;

//	Create the object to store the current ID
//----------------------------------------------------------------------------------------------
    Set<ID> contactID = new Set<ID>();
    Set<ID> ownerID = new Set<ID>();

//	Set Variables
//----------------------------------------------------------------------------------------------
    integer magicLimit = 20;

//  Collect the Contact ID from the current record
//----------------------------------------------------------------------------------------------
    FOR(Contact objCont : sContact)
    {
        contactID.add(objCont.Id);
        ownerID.add(objCont.OwnerId);
    }

//	Select all the records that this user might have as a Magic Mover
//----------------------------------------------------------------------------------------------
    integer intContacts = [SELECT count() FROM Contact WHERE OwnerID IN :ownerID AND CCC_Adviser__c = TRUE];

    FOR( Contact cont : trigger.new)
    {
        IF (intContacts > magicLimit)
        {
// Error occrs here
            sContact.addError('The Owner of this contact already has ' + magicLimit + ' Contacts on the Magic Movers List');
        }
        else
        {
// Error occurs here
            sContact.addError('Contact Count is: ' + intContacts);
        }
    }

}

 
I am having issues with the CPU limit when sending out emails. The ideal scenario is to be able to send out 1000 emails in a hit but if I try that it exceeds the limits of the CPU. I can send 150 a time which is good but not entirely the best option for use at this point.

I am sending it this way rather than via ExactTarget or similar as we don't currently have connections to these services and we are sending attachments to the recipients.

Any thoughts as to where I should start to reduce the CPU impact so that I can increase the number of emails that I can send in one schedule execution?

Screen shot of Log File

 
//------------------------------------------------------------------------------------------------------
    //--
    //--    send_mailout
    //--
    //--    Use:
    //--    This is the process to actually send the email and will be triggered by a scheduled APEX
    //--
    //--
    //------------------------------------------------------------------------------------------------------
    PUBLIC VOID send_mailout(STRING mailOutName, INTEGER iTotalSend)
    {
        //--    Our variables
        BOOLEAN sndSuccess = FALSE;
        
        strTemplate_Initial = mailOutName;
        strTemplate_Password = mailOutName + ' - Password';

        //--    Set the FROM email address
        //--	------------------------------------
        for(OrgWideEmailAddress owa : [SELECT id, Address, DisplayName FROM OrgWideEmailAddress WHERE DisplayName = 'CommInsure Communications']) 
        {
            strEmailFrom = owa.id;
        } 

        //--    Get the details of who we are going to send to
        //--	----------------------------------------------------
        objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c 
                      FROM ci_mailout__c 
                      WHERE Sent__c = FALSE 
                      AND Mailout_name__c = :strTemplate_Initial 
                      ORDER BY Policy_count__C Desc 
                      LIMIT :iTotalSend];
        FOR( ci_mailout__c mo : objMailout )
        {	mailoutIDs.add( mo.Id );	}

        //--	Create some attachment maps
        MAP<ID, String> mName = NEW MAP<ID, String>();
        MAP<ID, BLOB> mBody = NEW MAP<ID, BLOB>();
        MAP<ID, String> mContentType = NEW MAP<ID, String>();
        objAttachment = [SELECT ID, ParentID, Name, ContentType, body FROM attachment WHERE ParentId IN :mailoutIDs];
        FOR( attachment thisAttachment : objAttachment )
        {
            mName.put( thisAttachment.ParentID, thisAttachment.Name );
            mBody.put( thisAttachment.ParentID, thisAttachment.body );
            mContentType.put( thisAttachment.ParentID, thisAttachment.ContentType );
        }
        
        SYSTEM.debug(thisScript + 'Size of Mailout: ' + objMailout.size());

        //--    Get out templates
        //--	--------------------------------------------------------------------
        objTemplate_email = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Initial];
        FOR(EmailTemplate thistemplate_email: objTemplate_email)
        {
            template_email_id = thisTemplate_email.id;
            SYSTEM.debug(thisScript + 'Initial Template: ' + thisTemplate_email.Name);
        }

        objTemplate_password = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Password];
        FOR(EmailTemplate thistemplate_password: objTemplate_password)
        {
            template_password_id = thistemplate_password.id;
            SYSTEM.debug(thisScript + 'Password Template: ' + thistemplate_password.Name);
        }

        
        //--    Loop through the objMailout list and create the emails to be sent
        //--	--------------------------------------------------------------------
        FOR (ci_mailout__c thisMailOut: objMailout) 
        {
        	SYSTEM.debug(thisScript + 'Looping through the mailout data');
            Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
            email.setTargetObjectId(thisMailOut.contact__c);
            email.setTemplateId(template_email_id);
            email.setSaveAsActivity( TRUE );
            email.setToAddresses(new String[] { thisMailout.email_address__c });
            email.setTreatTargetObjectAsRecipient(FALSE);
            email.setUseSignature(FALSE);
            email.setWhatId(thisMailout.Id);
            email.setOrgWideEmailAddressId(strEmailFrom);

			//--    Get the Email Attachment
			//--	------------------------
            SYSTEM.debug(thisScript + 'No Attachments: ' + objAttachment.size());
            IF( mName.keySet().contains(thisMailout.Id) )
            {
                SYSTEM.debug(thisScript + 'Looping through Attachment');
                Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
                efa.setFileName( mName.get(thisMailout.Id));
                efa.setBody( mBody.get( thisMailout.Id ));
                efa.setContentType( mContentType.get( thisMailout.Id ));
                email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
            }

            //--	Add the email to the msgList for sending & keep track of the totalSend
            //--	----------------------------------------------------------------------------
            msgList.add(email);
            iCountTotalSend++;

            //--	Check and add the attachment if we need too
            //--	------------------------------------------------------------
            SYSTEM.debug(thisScript + 'Check if we have a password template');
            IF ( objTemplate_password.size() > 0 )
            {
                SYSTEM.debug(thisScript + 'Creating Password Email');
                Messaging.SingleEmailMessage email_pass = new Messaging.SingleEmailMessage();
                email_pass.setToAddresses(new String[] { thisMailout.email_address__c });
                email_pass.setTreatTargetObjectAsRecipient(FALSE);
                email_pass.setTargetObjectId(thisMailOut.contact__c);
                email_pass.setTemplateId(template_password_id);
                email_pass.setSaveAsActivity( TRUE );
                email_pass.setUseSignature( FALSE );
                email_pass.setOrgWideEmailAddressId(strEmailFrom);
                email_pass.setWhatId(thisMailout.Id);

                //--	Add the email to the msgList for sending & keep track of the totalSend
                //--	----------------------------------------------------------------------------
                msgList.add(email_pass);
                iCountTotalSend++;
            }

            //--	Now that we have created the email to be sent, let us update the details of the mailout so we can track once it is actuall sent
            //--	--------------------------------------------------------------------------------------------------------------------------------
            thisMailout.Sent__C = TRUE;
            thisMailout.Sent_Date__c = SYSTEM.now();
            updateMailout.add( thisMailout );

            //--	Check to see if we need to send a batch out because we are at the end
            //--	------------------------------------------------------------------------
            SYSTEM.DEBUG(thisScript + 'Message List size: ' + msgList.size());
            IF( msgList.size() == iBatchSize || objMailout.size() == iCountTotalSend )
            {
                List<Messaging.SendEmailResult> results = Messaging.sendEmail( msgList, false );
                IF(!results.get(0).isSuccess())
                {
                    SYSTEM.DEBUG(thisScript + 'This was unsuccessful: ' + results[0].getErrors().get(0).getMessage());
                    BREAK;
                }
                ELSE
                {
                    SYSTEM.DEBUG( thisScript + 'We have successfully sent a batch of emails. ' + iCountTotalSend + ' of ' + objMailout.size() );
                    msgList.clear();
    
                    //--	Now that we have update the send list so we don't send out again
                    //--	------------------------------------------------------------------------------------------------
                    TRY{ update updateMailout; }
                    CATCH ( Exception ex )
                    {	 SYSTEM.DEBUG(thisScript + 'Could not update the Mailout. Cause: ' + ex.getCause() );	updateMailout.clear();	}
                }
            }	//--	End Sending out the batches	
        }	//--	End Looping throught objMailout
    }	//--	End send_mailout

 
I am trying to get back a count of records in the task / event object for contacts so that I can update a contact field with the correct vale of activity.

I am passing a LIST<ID> to the function. The trouble appears on the highlighted lines below
LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs];
LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs];

The Error I get is:
Field must be grouped or aggregated: WhoId

But if I try and group it, it gives me errors as well
LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs GROUP BY WHOID];
LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs GROUP BY WHOID];
This gives the error
Illegal assignment from List<AggregateResult> to List<Task>


 

The Function
PUBLIC VOID updateActivityCount( LIST<ID> listContacts )
	{
        LIST<ID> ContactIDs = NEW LIST<ID>();
		ContactIDs = listContacts;

		INTEGER tmpTasks = 0;
		INTEGER tmpEvents = 0;

		
		LIST<CONTACT> contactUpdate = NEW LIST<CONTACT>();
		MAP<ID, INTEGER> contactTasks = NEW MAP<ID, INTEGER>();
		MAP<ID, INTEGER> contactEvents = NEW MAP<ID, INTEGER>();

        LIST<TASK> objTasks = [SELECT WHOID, count(ID) FROM TASK WHERE WHOID IN :ContactIDs];
        LIST<EVENT> objEvents = [SELECT WHOID, count(ID) FROM EVENT WHERE WHOID IN :ContactIDs];

		FOR(TASK thisTask : objTasks)
		{	contactTasks.put(thisTask[0], thisTask[1]);	}

		FOR(EVENT thisEvent : objEvents)
		{	contactEvents.put(thisEvent[0], thisEvent[1]);	}

		LIST<CONTACT> objContacts = [SELECT ID FROM Contact WHERE ID IN :ContactIDs];
		FOR(CONTACT thisContact : objContacts)
		{
			IF( contactTasks.containsKey( thisContact.Id ) )
			{	tmpTasks = contactTasks.get( thisContact.Id );	}
			ELSE
			{	tmpTasks = 0;	}

			IF( contactEvents.containsKey( thisContact.Id ) )
			{	tmpTasks = contactEvents.get( thisContact.Id );	}
			ELSE
			{	tmpEvents = 0;	}

			thisContact.activity_this_cfy__c = tmpTasks + tmpEvents;
			contactUpdate.add( thisContact );
		}

		//--    Execute the update for contactUpdate
		//------------------------------------------------------------------------------------------------------------------------------
		if ( !contactUpdate.isEmpty() )
		{
			TRY{ update contactUpdate; }
			CATCH ( Exception ex )
			{   SYSTEM.DEBUG(thisPage + 'Could not update Contact. Cause: ' + ex.getCause() );  }
		}
	}	//--	END updateActivityCount


 
Hi

Iam attempting to reduce the number of SOQL's being triggered to avoid the limits.

I currently have two queiries. The first brings back the mailout items and the second brings back the attachements for the mailout items

Get the mailout items
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];
Get the attachments for the above mailout items
objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];
So ... the above works but gets close to the limit for SOQL

So when I try to join the SOQL into 1 I get the following error
A driving SObject type has already been set, all other entity types in the FROM clause must be relationships to the initial object.  The driving object is CI_Mailout__c.
This is the query that I am attempting to use
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c, attachment WHERE ID = :[SELECT PARENTID FROM ATTACHMENT] AND Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];

Any guidance would be greatly appreciated.

Thanks


 
I am attempting to create a trigger that will update certain fields if the value in a multipicklist is present.

Rather than have 20 If statements to check if the value is in it, I want to be able to something like 

IF taskListValue is in picklistValue
THEN fieldToUpdate = fieldListValue.indexof( taskListValue.indexof( picklistValue )

It would then say something like ...

thisRecord.fieldToUpdate = TRUE

updateObject.add(thisRecord);

What I currently have is
 
//-- Some Varaibles to start with

STRING strRelated = thisTask.Campaign_Related__c;
STRING[] strRelated_split = strRelated.split(';');

LIST<STRING> lstOfTasks = NEW LIST<STRING>(); //-- Stores the values that can be in the multipicklist thisTask.Campaign_Related__c
LIST<STRING> lstOfFields = NEW LIST<STRING>(); //-- Stores the field names that we want to update if the values is passed. These are in the same sequence so getting the index of one will refer to the index of the other.

//-- Add some values to our lists
lstOfTasks.add('EDU - Business Insurance Session');
lstOfFields.add('Business_Insurance_Session_Completed__c');
lstOfTasks.add('EDU - CBA/CFP Branch Training Session');
lstOfFields.add('CBA_CFP_Branch_Training_Session_Complete__c');
lstOfTasks.add('EDU - Client Seminars');
lstOfFields.add('Client_Seminars_Completed__c');


FOR(intCount = 0; intCount < strRelated_split.size() ; intCount++)
{
    IF( strReleated_split[intCount] is in lstOfTasks)
    {
        intX = lstOfTasks.indexOf( strReleated_split[intCount] );
        theField = lstOfFields[intX]
        thisAMP.thisField = TRUE;
    }
}
Any help would be appreciated.
 
I am getting the following error whe I attempt to execute a query.
 
Line: 4, Column: 14
Didn't understand relationship 'attachment' in FROM part of query call. If you are attempting to use a custom relationship, be sure to append the '__r' after the custom relationship name. Please reference your WSDL or the describe call for the appropriate names.
The query (being executed via the debug in developer console
PUBLIC STRING strTemplate_Initial;
strTemplate_Initial = 'TEST EMAIL';

PUBLIC LIST <ci_mailout__c> objMailout;

objMailout = [SELECT m.Id, m.contact__c, contact__r.Name, m.recipient_first_name__c, m.recipient_last_name__c, caps__r.AccountID__c, m.file_password__c, m.email_address__c, (SELECT ID, Name, ContentType, body FROM attachment) FROM ci_mailout__c m WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 100];

SYSTEM.debug('Size of Mailout: ' + objMailout.size());

The code I originally had was two seperate queries on for the mailout and one for attachements which worked, however, it starts to hit the limit for SOQL statements and so I was thinking I could join the two statements to reduce the calls.

Original SOQL (in isolation)
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 50];

objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];

Thanks for your help ...



 
I have an issue where I am sending out SingleEmailMessage on mass using a visualforce enail template. Some of the information is in a custom object c0_mailout__c which I have in the email template as the relatedtotype. When I execite the script to test it, the email that I receive doesn't have the related details I am after (ci_mailout__c.file_password__c, ci_mailout_file_name__c). In debugging, I note that the relatedto ID doesn't appear to be present when the email is generated.

Based on this, I believe that my script isn't passing the relatedto information that the template requires. Is there a way using SingleEmailMessage to pass the relatedtoid to the email template?

Apex Class CI_Mailout
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------
//--
//--	Name:
//--	CI_MailOut
//--
//--	Purpose:
//--	Used in conjunction with CI_Mailout__c
//--
//--	Created by:
//--	Andrew Telford
//--
//--	Date:
//--	2016-06-02
//--
//------------------------------------------------------------------------------------------------------
//------------------------------------------------------------------------------------------------------

PUBLIC class CI_MailOut {

	PUBLIC CI_Mailout() {}

	PUBLIC ID mailoutID { get; set; }
	PUBLIC ID contactID { get; set; }
	PUBLIC LIST<CI_MAILOUT__C> objPasswords{ get; set; }

    PUBLIC LIST <ci_mailout__c> objMailout;
	PUBLIC LIST <attachment> objAttachment;
	PUBLIC LIST <Messaging.SingleEmailMessage> msgList = new List <Messaging.SingleEmailMessage> ();
	PUBLIC LIST <CI_MAILOUT__C> updateMailout = NEW LIST<CI_MAILOUT__C>();
	PUBLIC LIST <EmailTemplate> objtemplate_email;
	PUBLIC LIST <EmailTemplate> objtemplate_password;

    PUBLIC STRING strTemplate_Initial;
	PUBLIC STRING strTemplate_Password;
	PUBLIC STRING strEmailFrom;
	PUBLIC STRING template_email_id;
	PUBLIC STRING template_password_id;

    STRING thisScript = 'CI_Mailout.apxc: ';

	//------------------------------------------------------------------------------------------------------
	//
	//--	get_mail_attachment
	//--
	//--	Use:
	//--	This is used as a component for visual force emails generated from ci_mailout__c
	//
	//------------------------------------------------------------------------------------------------------
	PUBLIC LIST<attachment> get_mail_attachment()
	{
		LIST<attachment> objAttachments;
		objAttachments = [SELECT ID FROM Attachment WHERE ParentID = :mailoutID];
		RETURN objAttachments;
	}

	PUBLIC LIST<CI_MAILOUT__C> getPassword()
	{
		objPasswords = [SELECT recipient_first_name__c, recipient_last_name__c, File_Name__c, File_Password__c FROM CI_MAILOUT__C WHERE ID = :mailoutID];
        SYSTEM.DEBUG(thisScript + 'getPassword - objPasswords size: ' + objPasswords.size());
		RETURN objPasswords;
	}

	//------------------------------------------------------------------------------------------------------
	//--
	//--	send_mailout
	//--
	//--	Use:
	//--	This is the process to actually send the email and will be triggered by a scheduled APEX
	//--
	//--
	//------------------------------------------------------------------------------------------------------
	PUBLIC VOID send_mailout(STRING mailOutName)
	{
		//--	Our variables
		BOOLEAN sndSuccess = FALSE;
		
		strTemplate_Initial = mailOutName;
		strTemplate_Password = mailOutName + ' - Password';

		//--	Set the FROM email address
		for(OrgWideEmailAddress owa : [select id, Address, DisplayName from OrgWideEmailAddress]) 
		{
			strEmailFrom = owa.id;
		} 

		//--	Get the details of who we are going to send to
		objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE AND Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 500];
		SYSTEM.debug(thisScript + 'Size of Mailout: ' + objMailout.size());

		//--	Get the Mailtemplate that we are going to use
		objTemplate_email = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Initial];
		FOR(EmailTemplate thistemplate_email: objTemplate_email)
		{
			template_email_id = thisTemplate_email.id;
			SYSTEM.debug(thisScript + 'Initial Template: ' + thisTemplate_email.Name);
		}

		objTemplate_password = [SELECT id, Name FROM EmailTemplate WHERE Name = :strTemplate_Password];
		FOR(EmailTemplate thistemplate_password: objTemplate_password)
		{
			template_password_id = thistemplate_password.id;
			SYSTEM.debug(thisScript + 'Password Template: ' + thistemplate_password.Name);
		}

		FOR (ci_mailout__c thisMailOut: objMailout) {
		SYSTEM.debug(thisScript + 'Looping through the mailout data');
			Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
			email.setTargetObjectId(thisMailOut.contact__c);
			email.setTemplateId(template_email_id);
			email.setSaveAsActivity(true);
			email.setToAddresses(new String[] { thisMailout.email_address__c });
			email.setTreatTargetObjectAsRecipient(FALSE);
			email.setUseSignature(FALSE);
			email.setOrgWideEmailAddressId(strEmailFrom);

		//--	Get the Email Attachment
			objAttachment = [SELECT ID, Name, ContentType, body FROM attachment WHERE ParentId = :thisMailOut.Id];
			SYSTEM.debug(thisScript + 'No Attachments: ' + objAttachment.size());
			if( objAttachment.size() > 0)
			{
				FOR(attachment thisAttachment: objAttachment)
				{
					SYSTEM.debug(thisScript + 'Looping through Attachment');
					Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
					efa.setFileName(thisAttachment.Name);
					efa.setBody(thisAttachment.body);
					efa.setContentType(thisAttachment.ContentType);
					email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
				}
			}

			msgList.add(email);

			SYSTEM.debug(thisScript + 'Check if we have a password template');
			IF ( objTemplate_password.size() > 0 )
			{
				SYSTEM.debug(thisScript + 'Creating Password Email');
				Messaging.SingleEmailMessage email_pass = new Messaging.SingleEmailMessage();
				email_pass.setToAddresses(new String[] { thisMailout.email_address__c });
				email_pass.setTreatTargetObjectAsRecipient(FALSE);
				email_pass.setTargetObjectId(thisMailOut.contact__c);
				email_pass.setTemplateId(template_password_id);
				email_pass.setSaveAsActivity(true);
				email_pass.setUseSignature(FALSE);
				email_pass.setOrgWideEmailAddressId(strEmailFrom);
				msgList.add(email_pass);
			}
		}

		SYSTEM.DEBUG(thisScript + 'Message List size: ' + msgList.size());
		IF( msgList.size() > 0 )
		{
			List<Messaging.SendEmailResult> results = Messaging.sendEmail( msgList, false );
			IF(!results.get(0).isSuccess())
			{
   				SYSTEM.DEBUG(thisScript + 'This was unsuccessful: ' + results[0].getErrors().get(0).getMessage());
			}
			ELSE
			{
   				FOR( CI_MAILOUT__C thisMailout: objMailOut)
				{
					thisMailout.Sent__C = TRUE;
					thisMailout.Sent_Date__c = SYSTEM.now();
					updateMailout.add( thisMailout );
				}

				IF( !updateMailout.isEmpty() )
				{
					update updateMailout;
				}
			}
			System.debug(thisScript +  results );
		}
	}
}



VisualForce Component ci_mailout_password
<apex:component controller="CI_MailOut" access="global">
    <apex:attribute name="mailID"
        type="Id"
        description="Mailout Reference"
        assignTo="{!mailoutID}" />

        <apex:repeat value="{!Password}" var="p">

            <p>Dear {!p.Recipient_First_Name__c}</p>
            <p>Here is your password to access your CommInsure client list. These clients will shortly receive information about CommInsure’s enhancement to medical definitions.</p>
            <ul>
                <li>File Name: {!p.File_Name__c} </li>
                <li>Password: {!p.File_Password__c}</li>
            </ul>
        </apex:repeat>
</apex:component>



Visualforce Email Template
<messaging:emailTemplate subject="File password for enhancement of medical definitions communications to CommInsure clients" recipientType="Contact" relatedToType="CI_Mailout__c" replyTo="">

    <messaging:HtmlEmailBody >
        <html>
            <head>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <meta name="viewport" content="width=device-width, initial-scale=1.0" />
                <meta name="format-detection" content="telephone=no" />
                <meta name="format-detection" content="date=no" />
                <meta name="format-detection" content="address=no" />
                <meta name="format-detection" content="time=no" />
                <c:ci_email_style_sheet />
            </head>
            <body style="-moz-osx-font-smoothing: grayscale; -ms-text-size-adjust: 100%; -webkit-font-smoothing: antialiased; -webkit-tap-highlight-color: transparent; -webkit-text-size-adjust: none; -webkit-touch-callout: none; margin: 0px; padding: 0px; width: 100% !important">



<!--    Email Header - End  -->

<!--    Email Content   -->
                                                                                        <h3>File password for enhancement of medical definitions communications to CommInsure clients</h3>
<p>Related to: {!RelatedTo.Id}</p><!-- DEBUG-->
<p>Related Name: {!relatedTo.Name}</p><!-- DEBUG-->

<c:CI_MailOut_Password mailID="{!relatedTo.id}" />
<p>If you have any questions, please contact your Business Development Manager.</p>

<!--    Email Content - End -->

<!--    Email Signature -->
<c:ci_email_signature />
<p>&nbsp;</p>
<p>&nbsp;</p>

<!--    Email Footer    -->

            </body>
        </html>
    </messaging:HtmlEmailBody>
</messaging:emailTemplate>

 
Hi

I have a custom object ci_mailout and it has a picklist filed called mailout_name__c. When I create the following query, it tells me that there is an unexpected ';'. From what I can see there isn't anything unexpected. Is it something to do with the picklist??
 
objMailout = [SELECT Id, contact__c, contact__r.Name, recipient_first_name__c, recipient_last_name__c, caps__r.AccountID__c, file_password__c, email_address__c FROM ci_mailout__c WHERE Sent__c = FALSE, Mailout_name__c = :strTemplate_Initial ORDER BY Policy_count__C Desc LIMIT 250];

note that objMailout has been declared earlier (PUBLIC LIST <ci_mailout__c> objMailout;) in the script.
I am attempting to use a frame work (http://chrisaldridge.com/triggers/lightweight-apex-trigger-framework/) and I am running in to an issue when I attempt to loop thorugh a MAP that is passed to a class.

This is the code I currently have
public void AfterInsert( Map<Id, SObject> newItems )
{
//– Collect the common information
//———————————————————————————————————————-
List<Contact> contsToUpdate = new List<Contact>();
List<Contact> updateContacts = new List<Contact>();
Set<<D> contactIDs = new Set<ID>();
List<Task> thisTask = new List<Task>();

SYSTEM.debug('Where Are We?: AfterInsert Task');
SYSTEM.debug('What type of object?: ' + newItems.getSObjectType() );
SYSTEM.debug('What is our Size: ' + newItems.size() );
SYSTEM.debug('Who?: ' + newItems.get('WhoId') );

Map<Id, Task> MyMap = new Map<Id, Task>(newItems); //– Error here 
thisTask.addAll(MyMap.values());
}

This is the error I get when I save the TaskTriggerHandler class
Invalid initial type Map<Id,SObject> for Map<Id,Task>

What am I missing?.
 
Hi

I am getting the above error but can't seem to locate exactly what the issue is. A few other posts suggest that I need to remove the DML from within the For loops. I believe I have done this unless I am missing something.

Can the community assist me in this please?
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-07-31
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Contact on Contact ( after insert, after update, after delete, after undelete) 
{

//  Let us prepare some common variables
//----------------------------------------------------------------------------------------------
    system.debug('Set the variables');

    // Common items
    STRING thisContactID;
    STRING thisContactOwnerID;
    STRING userID;
    STRING userProfileID;
    STRING errMsg = '';


//--    Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
    system.debug('Contact[]');

//--    Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
    Contact[] strContact;

    if (Trigger.isDelete) 
    {   strContact = Trigger.old;   }
    else
    {   strContact = Trigger.new;   }

    Set<ID> contactID = new Set<ID>();
	Set<ID> ownerIds = new Set<ID>();
	Set<ID> oldOwnerIds = new Set<ID>();
    for(Contact objCont: strContact)
    {
        ownerIds.add(objCont.ownerId);
        if ( !TRIGGER.isInsert && !TRIGGER.isunDelete )
        {	
            oldOwnerIds.add(TRIGGER.oldMap.get(objCont.Id).ownerId);
        }
    }


    LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :strContact AND Approved_Owner_Change__c = TRUE];
    LIST<User> thisOwner = [Select Id FROM User WHERE ID IN :ownerIds];
	LIST<Contact> ownerMMCount = [SELECT Id FROM Contact WHERE ownerId IN :ownerIds AND CCC_Adviser__c = TRUE];
    LIST<User> oldOwner = [Select Id FROM User WHERE ID IN :oldOwnerIds];
    LIST<Contact> oldOwnerMMCount = [SELECT Id FROM Contact WHERE ownerId IN :oldOwnerIds AND CCC_Adviser__c = TRUE];

    FOR(Contact objCont: strContact)
    {
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Owner Change Approved
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

        system.debug('Set the variable values');

    //--    Define any variables required
    //----------------------------------------------------------------------------------------------
        BOOLEAN approvedOwnerChange;
        STRING newContactID = '';

    //--    Assign Values to Variables
    //----------------------------------------------------------------------------------------------
        contactID.add(objCont.Id);
        thisContactID = objCont.Id;
        thisContactOwnerID = objCont.OwnerId;
        userID = userinfo.getUserId();
        userProfileID = userinfo.getProfileId();
        approvedOwnerChange = objCont.Approved_Owner_Change__c;

        system.debug('Determine if owner is to change');

    //--    Check for change forced by workflow
    //----------------------------------------------------------------------------------------------

		if ( !TRIGGER.isAfter && !TRIGGER.isDelete )
        {
            if( objCont.Approved_Owner_Change__c )
            {

    //--    Check to see if we are updating the owner
    //----------------------------------------------------------------------------------------------
                if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
                {
					system.debug('Owner is to change');

    //--    Set the update list
    //----------------------------------------------------------------------------------------------
	                List<Contact> updateOwner = new List<Contact>();

                    FOR (Contact cont: contsToUpdate)
                    {
	                    Boolean alterOwner = FALSE;

                        IF ( cont.Approved_Owner_Change__c = TRUE )
                        {   alterOwner  = TRUE; }

                        if (alterOwner) 
                        {
                            cont.OwnerID = cont.Approved_Owner_Name__c;
                            cont.Approved_Owner_Change__c = FALSE;
                            newContactID = cont.Approved_Owner_Name__c;
                        }
                        updateOwner.add(cont);
                    }


    //--    Execute the update
    //----------------------------------------------------------------------------------------------
                    if (!updateOwner.isEmpty()) 
                    {
                        try{ update updateOwner; }
                        catch (Exception ex)
                        { System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
                    }
                }
            }   //--    End Check for automated change after insert
        }
//
//  End Approve Owner Change
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
//
//  Magic Movers
//
//  This works in conjunction with:
//      Validations
//          Magic Mover Addition (03dc00000009014)
//          Magic Mover REmoval (03dc00000009080)
//
//      Workflow Field Update
//          New Contact (01Q20000000Es9Z)
//          Set Magic Mover to False (04Yc000000090G1)
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

    //--    Magic Movers 
        BOOLEAN magicMover;
        DECIMAL userMagicCount;

    //--    Select the Owner Information
        LIST<User> updateMM = new LIST<User>();
        system.debug( 'Size of thisUser: ' + thisOwner.size());

		FOR ( User mm1: thisOwner )
        {
            mm1.Magic_Movers_Count__c = ownerMMCount.size();
            updateMM.add(mm1);

        }   //--    For Current Owner Loop

    //--    Process the updates
    //------------------------------------------------------------------------------------------------------------------------------
        system.debug('size of: ' + updateMM.size());
        if (!updateMM.isEmpty()) 
        {
            try{ update updateMM; }
            catch (Exception ex)
            { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
        }

	//--	Check to see if the Owner has changed
	//-----------------------------------------------------------------------------------------------------------------------------
        LIST<User> updateOldMM = new LIST<User>();
        system.debug( 'Size of oldOwner: ' + oldOwner.size());

		FOR ( User mm2: oldOwner )
        {
            mm2.Magic_Movers_Count__c = oldOwnerMMCount.size();
            updateOldMM.add(mm2);

        }   //--    End For Old Owner Loop

	//--    Process the updates
    //------------------------------------------------------------------------------------------------------------------------------
        system.debug('size of: ' + updateOldMM.size());
        if (!updateOldMM.isEmpty()) 
        {
            try{ update updateOldMM; }
            catch (Exception ex)
            { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
        }


//
//  End Magic Movers
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

    }
//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}

 
Hi

I am trying to get a trigger based on Contact to funciton but I am continually getting an error relating to too many SOQL Queries. The error states I am getting the error on Line 60.

Should I create a 2nd Contact Trigger file and have it only execute AFTER update?
LIST<Contact> thisCount = [SELECT Id FROM Contact WHERE OwnerId IN :ownerIds AND CCC_Adviser__c = TRUE];
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Trigger_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-08-17
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Trigger_Contact on Contact ( after insert, after update, before update, after delete, after undelete) 
{

//	Let us prepare some common variables
//----------------------------------------------------------------------------------------------
system.debug('Set the variables');

	// Common items
	STRING thisContactID;
	STRING thisContactOwnerID;
	STRING userID;
	STRING userProfileID;
	STRING errMsg = '';


//--	Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
system.debug('Contact[]');

//--	Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
	Contact[] strContact;

	if (Trigger.isDelete) 
	{	strContact = Trigger.old;	}
	else
	{	strContact = Trigger.new;	}

	Set<ID> contactID = new Set<ID>();
	Set<ID> ownerIds = new Set<ID>();
	for(Contact objCont: strContact)
	{	ownerIds.add(objCont.ownerId);	}

    //--	For Owner Change Approved
	//----------------------------------------------------------------------------------------------
	LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :strContact AND Approved_Owner_Change__c = TRUE];

    //--	For Magic Movers
	//----------------------------------------------------------------------------------------------
    LIST<User> thisOwner = [Select Id FROM User WHERE ID IN :ownerIds];
//-- Line 60 is below
    LIST<Contact> thisCount = [SELECT Id FROM Contact WHERE OwnerId IN :ownerIds AND CCC_Adviser__c = TRUE];

	FOR(Contact objCont: strContact)
	{

	//----------------------------------------------------------------------------------------------
	//----------------------------------------------------------------------------------------------
	//
	//  Owner Change Approved
	//
	//
	//

	//--	Define any variables required
	//----------------------------------------------------------------------------------------------
		system.debug('Set the variable values');
		BOOLEAN approvedOwnerChange;
		STRING newContactID = '';

	//--	Assign Values to Variables
	//----------------------------------------------------------------------------------------------
		contactID.add(objCont.Id);
		thisContactID = objCont.Id;
		thisContactOwnerID = objCont.OwnerId;
		userID = userinfo.getUserId();
		userProfileID = userinfo.getProfileId();
		approvedOwnerChange = objCont.Approved_Owner_Change__c;


	//--	Check to see if we are updating the owner
	//----------------------------------------------------------------------------------------------
		system.debug('Owner is to change');
		if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
		{

	//--	Set the update list
	//----------------------------------------------------------------------------------------------
			List<Contact> updateOwner = new List<Contact>();

			FOR (Contact cont: contsToUpdate)
			{
				Boolean alterOwner = FALSE;

				IF ( cont.Approved_Owner_Change__c )
				{
					cont.OwnerID = cont.Approved_Owner_Name__c;
					cont.Approved_Owner_Change__c = FALSE;
					newContactID = cont.Approved_Owner_Name__c;
					updateOwner.add(cont);
				}
			}


	//--	Execute the update
	//----------------------------------------------------------------------------------------------
			if (!updateOwner.isEmpty()) 
			{
				try{ update updateOwner; }
				catch (Exception ex)
				{ System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
			}
		}

	//
	//  End Approve Owner Change
	//
	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------


	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------
	//
	//  Magic Movers
	//
	//	This works in conjunction with:
	//		Validations
	//			Magic Mover Addition (03dc00000009014)
	//			Magic Mover REmoval (03dc00000009080)
	//
	//		Workflow Field Update
	//			New Contact (01Q20000000Es9Z)
	//			Set Magic Mover to False (04Yc000000090G1)
	//
	//
	//

	//--	Magic Movers 
	//------------------------------------------------------------------------------------------------------------------------------
		IF ( TRIGGER.isAfter )
        {
            BOOLEAN magicMover;
			DECIMAL userMagicCount;

	//--	Select the Owner Information
	//------------------------------------------------------------------------------------------------------------------------------
            system.debug( 'Size of thisUser: ' + thisOwner.size());
            LIST<User> updateUser = new LIST<User>();

            for ( User o1: thisOwner )
            {
                o1.Magic_Movers_Count__c = thisCount.size();
                updateUser.Add(o1);

            }	//--	For Owner Loop
	//--	Process the updates
	//------------------------------------------------------------------------------------------------------------------------------
                system.debug('size of: ' + updateuser.size());
                if (!updateUser.isEmpty()) 
                {
                    try{ update updateUser; }
                    catch (Exception ex)
                    { objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
                }
        }	//--	End Check for After          

	//
	//  End Magic Movers
	//
	//--------------------------------------------------------------------------------------------------------------------------------------
	//--------------------------------------------------------------------------------------------------------------------------------------
		//objCont.addError(errMsg);
	}

//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}

 
Hi

I have the following trigger that appears to be ok in the sandbox and in production it all validates. I tried to insert some contacts today using Apex Data Loader and got the error relating to too many SOQL queries.

I thought I had bulkified it but evidently this isn't the case. Can some one assist in pointing me in the right direction as to where I have gone wrong please.

Thanks
 
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Name:
//      CI_Trigger_Contact
//
//  Purpose:
//      This will process changes that need to be made based on fields that may change when 
//      contacts are inserted, edited, deleted and undeleted
//  
//  Created by:
//      Andrew Telford
//
//  Date: 
//      2015-07-31
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

trigger CI_Trigger_Contact on Contact ( after insert, after update, after delete, after undelete) 
{

//	Let us prepare some common variables
//----------------------------------------------------------------------------------------------
	system.debug('Set the variables');

	// Common items
	STRING thisContactID;
	STRING thisContactOwnerID;
	STRING userID;
	STRING userProfileID;
	STRING errMsg = '';


//--	Let us get the details relating to this contact change
//----------------------------------------------------------------------------------------------
	system.debug('Contact[]');

//--	Set the details of the trigger to a variable for use through the trigger
//----------------------------------------------------------------------------------------------
	Contact[] strContact;

	if (Trigger.isDelete) 
	{	strContact = Trigger.old;	}
	else
	{	strContact = Trigger.new;	}

	Set<ID> contactID = new Set<ID>();
	FOR(Contact objCont: strContact)
	{
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
//
//  Owner Change Approved
//
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------

		system.debug('Set the variable values');

	//--	Define any variables required
	//----------------------------------------------------------------------------------------------
		BOOLEAN approvedOwnerChange;
		STRING newContactID = '';

	//--	Assign Values to Variables
	//----------------------------------------------------------------------------------------------
		contactID.add(objCont.Id);
		thisContactID = objCont.Id;
		thisContactOwnerID = objCont.OwnerId;
		userID = userinfo.getUserId();
		userProfileID = userinfo.getProfileId();
		approvedOwnerChange = objCont.Approved_Owner_Change__c;

		system.debug('Determine if owner is to change');

	//--	Check for change forced by workflow
	//----------------------------------------------------------------------------------------------
		if( !objCont.Approved_Owner_Change__c && ( TRIGGER.newMap.get( objCont.Id ).OwnerId != '00520000000noZtAAI' || TRIGGER.newMap.get( objCont.Id ).OwnerId != '00520000000noZtAAI' ) )
		{

	//--	Check to see if we are updating the owner
	//----------------------------------------------------------------------------------------------
			if( TRIGGER.isupdate && objCont.Approved_Owner_Change__c )
			{
				system.debug('Owner is to change');
				LIST<Contact> contsToUpdate = [SELECT Id, OwnerId, Approved_Owner_Change__c, Approved_Owner_Name__c FROM Contact WHERE Id IN :contactID AND Approved_Owner_Change__c = TRUE];

	//--	Set the update list
	//----------------------------------------------------------------------------------------------
				List<Contact> updateOwner = new List<Contact>();

				FOR (Contact cont: contsToUpdate)
				{
					Boolean alterOwner = FALSE;

					IF ( cont.Approved_Owner_Change__c = TRUE )
					{	alterOwner  = TRUE;	}

					if (alterOwner) 
					{
						cont.OwnerID = cont.Approved_Owner_Name__c;
						cont.Approved_Owner_Change__c = FALSE;
						newContactID = cont.Approved_Owner_Name__c;
						updateOwner.add(cont);
					}
				}


	//--	Execute the update
	//----------------------------------------------------------------------------------------------
				if (!updateOwner.isEmpty()) 
				{
					try{ update updateOwner; }
					catch (Exception ex)
					{ System.debug('Could not update New Contact Owner [' + newContactID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact');}
				}
			}
		}	//--	End Check for automated change after insert



//
//  End Approve Owner Change
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------


//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
//
//  Magic Movers
//
//	This works in conjunction with:
//		Validations
//			Magic Mover Addition (03dc00000009014)
//			Magic Mover REmoval (03dc00000009080)
//
//		Workflow Field Update
//			New Contact (01Q20000000Es9Z)
//			Set Magic Mover to False (04Yc000000090G1)
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

	//--	Magic Movers 
		BOOLEAN magicMover;
		DECIMAL userMagicCount;

	//--	Select the Owner Information
		LIST<User> thisOwner = [Select Magic_Movers_Count__c FROM User WHERE ID = :objCont.OwnerID];
		LIST<User> updateUser = new LIST<User>();
		system.debug( 'Size of thisUser: ' + thisOwner.size());

		for ( User o1: thisOwner )
		{
			if( o1.Magic_Movers_Count__C == NULL )
			{ userMagicCount = 0; }
			else
			{ userMagicCount = o1.Magic_Movers_Count__C; }
            system.debug('No. of Magic Movers = ' + userMagicCount);

            if( !TRIGGER.isinsert && !TRIGGER.isUnDelete )
            {
                
	//--	Has Magic Mover been altered?
	//------------------------------------------------------------------------------------------------------------------------------
                if( objCont.CCC_Adviser__c != TRIGGER.oldMap.get( objCont.Id ).CCC_Adviser__c 
                    && TRIGGER.isupdate && thisContactOwnerID == userID )
                {
	//--	Check to see if the owner has the magic count limit and the change is an addition
	//------------------------------------------------------------------------------------------------------------------------------
                    if( userMagicCount < 21 && objCont.CCC_Adviser__c )
                    {
                        o1.Magic_Movers_Count__c = userMagicCount + 1;
                        updateUser.add(o1);
                        system.debug('size of: ' + updateuser.size());
                    }
                    else if ( !objCont.CCC_Adviser__c )
                    {
                        o1.Magic_Movers_Count__c = userMagicCount - 1;
                        updateUser.add(o1);
                        system.debug('size of: ' + updateuser.size());
                    }
                }
			//--	End check for change in Magic Mover

	//--	Reduce the count when the owner is changed
	//------------------------------------------------------------------------------------------------------------------------------
                else if ( TRIGGER.isUpdate && TRIGGER.isBefore && objCont.OwnerId != TRIGGER.oldMap.get( objCont.Id ).OwnerId )
                { objCont.CCC_Adviser__c = FALSE; }

	//--	When the contact is deleted, reduce the count
	//------------------------------------------------------------------------------------------------------------------------------
                else if ( TRIGGER.isDelete )
                {
                    o1.Magic_Movers_Count__c = userMagicCount - 1;
                    updateUser.add(o1);
                    system.debug('size of: ' + updateuser.size());
                }
                //--	End check for delete
            }

	//--	Process the updates
	//------------------------------------------------------------------------------------------------------------------------------
            system.debug('size of: ' + updateuser.size());
			if (!updateUser.isEmpty()) 
			{
				try{ update updateUser; }
				catch (Exception ex)
				{ objCont.addError(' Error Updating ' + ex.getCause()); System.debug('Could not update User [' + thisContactOwnerID + '] cause: ' + ex.getCause() + 'APEX TRIGGER: CI_Trigger_Contact'); }
			}
		}	//--	For Owner Loop

//
//  End Magic Movers
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------

	}
//
//  End Contact Loop
//
//--------------------------------------------------------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------------------------------------------------------
}