function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Golden10Golden10 

Cross Object Formula Task - Account

Hi All,
 
Need some help again guys. We keep track of the Quotes we send out via a task where the user selects Quote Sent from the Subject field once they send a quote. What i need to record at the Account level is what date was the last quote sent. Any ideas??
 
Cheers
 
Golden
Best Answer chosen by Admin (Salesforce Developers) 
JimRaeJimRae
OK, I tweaked one of my existing triggers, and testmethods, here you go, should be a good start for you.

Here is the trigger:

Code:
trigger QuoteSentTrigger on Task (after insert) {
 Map<ID,Datetime> QuoteSentMap = new Map<ID,Datetime>(); //this will map all affected Accounts by add and task createdby date
 
 //loop through all tasks in this transaction to support bulk load
 for(Task newTask:Trigger.new){
                //assumes the subject line you are looking for is 'Quote Sent' 
if(newTask.Subject.equals('Quote Sent')){ //checks to make sure the task is somehow related to an account
if(!(newTask.Accountid==null)){ QuoteSentMap.put(newTask.Accountid,newTask.CreatedDate); } } } //this will retrieve all Accounts that need to be updated, and assumes quotedate field on Account record has that api name and is a datetime type List<Account> updAccts = [select id,last_quote_sent__c from Account where id in :QuoteSentMap.keyset()]; if(UpdAccts.size()>0){ for(Account a:updAccts){ a.last_quote_sent__c=QuoteSentMap.get(a.id); //set the field to the new value } try{ update updAccts; //update all account records with one DML statement }catch(DMLException e){ system.debug('\n\nERROR Updating Accounts:'+e.getDMLMessage(0));//catch any errors that might occur } } }

 
Here is the testmethod to test it (required for deployment to production):

Code:
/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class TestQuoteSentTrigger {

    static testMethod void myUnitTest() {
        String TestAcctID='';
        String TestTaskID='';
        Account testAcct = new Account(name='Test Account');//create a test account for portability
        try{
         insert testAcct;
         TestAcctID=testAcct.ID;
        }catch(DMLException e){
         system.debug('\n\nError occurred inserting test account:'+e.getDMLMessage(0));
        }
        Task testTask = new Task(subject='Quote Sent',whatid=TestAcctID);//create new task for testing, related to test account
        try{
         insert testTask;
         TestTaskID=testTask.id;
        }catch(DMLException e){
         system.debug('\n\nError occurred inserting test task:'+e.getDMLMessage(0));
        }
        //Validate that our trigger worked
        Account checkAcct= [select id,last_quote_sent__c from Account where id =:TestAcctID];
        system.debug('\n\nTest Account: '+checkAcct);
        Task checkTask=[select id,createddate from Task where id=:TestTaskID];
        system.debug('\n\nTest Task'+checkTask);
        system.assertequals(checkAcct.last_quote_sent__c,checkTask.createddate);
    }
}

 

All Answers

JimRaeJimRae
Not sure about a cross object formula, couldn't see how to make that work.  I would say a fairly easy trigger on the tasks that looks for the subject of "Quote Sent" and then updates the related Account records "Last quote Sent" field with the current date.


Golden10Golden10
Thanks Jim, however I havent got myself stuck into apex triggers yet. I have since looked into the force.com cookbook and
going through it. Are you able to assist me in wrting the simple trigger? I have other areas which i want to use similar triggers and this would be a base start.
 
Much appreciated.
 
Golden
JimRaeJimRae
OK, I tweaked one of my existing triggers, and testmethods, here you go, should be a good start for you.

Here is the trigger:

Code:
trigger QuoteSentTrigger on Task (after insert) {
 Map<ID,Datetime> QuoteSentMap = new Map<ID,Datetime>(); //this will map all affected Accounts by add and task createdby date
 
 //loop through all tasks in this transaction to support bulk load
 for(Task newTask:Trigger.new){
                //assumes the subject line you are looking for is 'Quote Sent' 
if(newTask.Subject.equals('Quote Sent')){ //checks to make sure the task is somehow related to an account
if(!(newTask.Accountid==null)){ QuoteSentMap.put(newTask.Accountid,newTask.CreatedDate); } } } //this will retrieve all Accounts that need to be updated, and assumes quotedate field on Account record has that api name and is a datetime type List<Account> updAccts = [select id,last_quote_sent__c from Account where id in :QuoteSentMap.keyset()]; if(UpdAccts.size()>0){ for(Account a:updAccts){ a.last_quote_sent__c=QuoteSentMap.get(a.id); //set the field to the new value } try{ update updAccts; //update all account records with one DML statement }catch(DMLException e){ system.debug('\n\nERROR Updating Accounts:'+e.getDMLMessage(0));//catch any errors that might occur } } }

 
Here is the testmethod to test it (required for deployment to production):

Code:
/**
 * This class contains unit tests for validating the behavior of Apex classes
 * and triggers.
 *
 * Unit tests are class methods that verify whether a particular piece
 * of code is working properly. Unit test methods take no arguments,
 * commit no data to the database, and are flagged with the testMethod
 * keyword in the method definition.
 *
 * All test methods in an organization are executed whenever Apex code is deployed
 * to a production organization to confirm correctness, ensure code
 * coverage, and prevent regressions. All Apex classes are
 * required to have at least 75% code coverage in order to be deployed
 * to a production organization. In addition, all triggers must have some code coverage.
 * 
 * The @isTest class annotation indicates this class only contains test
 * methods. Classes defined with the @isTest annotation do not count against
 * the organization size limit for all Apex scripts.
 *
 * See the Apex Language Reference for more information about Testing and Code Coverage.
 */
@isTest
private class TestQuoteSentTrigger {

    static testMethod void myUnitTest() {
        String TestAcctID='';
        String TestTaskID='';
        Account testAcct = new Account(name='Test Account');//create a test account for portability
        try{
         insert testAcct;
         TestAcctID=testAcct.ID;
        }catch(DMLException e){
         system.debug('\n\nError occurred inserting test account:'+e.getDMLMessage(0));
        }
        Task testTask = new Task(subject='Quote Sent',whatid=TestAcctID);//create new task for testing, related to test account
        try{
         insert testTask;
         TestTaskID=testTask.id;
        }catch(DMLException e){
         system.debug('\n\nError occurred inserting test task:'+e.getDMLMessage(0));
        }
        //Validate that our trigger worked
        Account checkAcct= [select id,last_quote_sent__c from Account where id =:TestAcctID];
        system.debug('\n\nTest Account: '+checkAcct);
        Task checkTask=[select id,createddate from Task where id=:TestTaskID];
        system.debug('\n\nTest Task'+checkTask);
        system.assertequals(checkAcct.last_quote_sent__c,checkTask.createddate);
    }
}

 

This was selected as the best answer
fredkafredka

Hi AAlbert... Thanks for helping me!!!  I should have realized that the same theory would apply with do loops as for loops....

 

I made the changes that you suggested.... however, when I try to deply, I still get the error:

 

System.DmlException: Insert failed First exception on row 0; first error; CANNOT INSERT_UPDATE_ACTIVATE_ENTITY, UpdateAccountHealthStatusToWon: exectution on beforeinsert

 

Thanks!!!

fredkafredka

Thanks so much for your help!!  I made the changes, however, I still get the following error when I try to deploy the trigger:

 

System.DmlException: Insert failed First exception on row 0; first error; CANNOT INSERT_UPDATE_ACTIVATE_ENTITY, UpdateAccountHealthStatusToWon: exectution on beforeinsert

 

Thanks!!!

fredkafredka
sorry, I posted my previous replies to the wrong post.....