1

I'm having trouble getting my test class to pass tests. Getting:

System.DmlException: Insert failed. First exception on row 0; first error: CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY, UpdateAccountActivityDescription: execution of AfterUpdate caused by: System.QueryException: List has no rows for assignment to SObject Trigger.UpdateAccountActivityDescription: line 6, column 1: []

as an error.

Trigger

trigger UpdateAccountActivityDescription on Task (after insert,after update) {
 if(Trigger.isAfter) {
        if(Trigger.isUpdate){
        for(Task t : Trigger.new) {
    // We need to update associated Opportunity Fields with Fields from Case.
    Account acc = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Account WHERE Id = :t.WhoId ];

    acc.Recent_Activity_Notes__c = t.Description;
    acc.Recent_Activity_Date__c = t.CreatedDate;
    acc.Recent_Activity_Owner__c = t.WhoId;


    update acc;
    }
    }
}
}

Test Class

@isTest
public class UpdateAccountActivityDecscription_Test {

    static testMethod void CreateAccountTask(){


        Account acc = new Account();
        acc.Name = 'Test Account';
        insert acc;
    }     

    static testMethod void CreateTask(){
        Account acc1 = new Account();
        acc1.Name = 'Test Account1';
        acc1.Recent_Activity_Notes__c = 'Test Version one';
        acc1.Recent_Activity_Date__c = date.parse('12/12/2013');
        insert acc1;

     Profile p = [SELECT Id FROM Profile WHERE Name = 'Standard User'];
        User u1 = new User(Alias = 'testa', Email ='[email protected]', EmailEncodingKey='UTF-8', LastName='Testing', LanguageLocaleKey='en_US', LocaleSidKey='en_US', ProfileId= p.Id,
                          TimeZoneSidKey= 'America/Los_Angeles', UserName= '[email protected]');

        System.runAs(u1) {

            Task t1 = New Task();
            t1.Subject = 'Task1 New';
            t1.Description = 'Update Task1 Name';
            t1.WhatId = acc1.id;
            insert t1;

            t1.Description = 'New New New Task1';
            update t1;

        }      
        }
}
1
  • Be careful as any task created against another type not related to an account will cause this to fail. Commented Nov 26, 2014 at 16:55

2 Answers 2

1

This trigger should fix the problem and is also bulkified:

trigger UpdateAccountActivityDescription on Task (after insert, after update) {
    Map<Id, Task> m = new Map<Id, Task>();
    for (Task t : Trigger.new) {
        if (t.AccountId != null) m.put(t.AccountId, t);
    }
    if (m.size() > 0) {
        Account[] accounts = new Account[] {};
        for (Id id : m.keySet()) {
            Task t = m.get(id);
            accounts.add(new Account(
                    Id = id,
                    Recent_Activity_Notes__c = t.Description;
                    Recent_Activity_Date__c = t.CreatedDate;
                    Recent_Activity_Owner__c = t.WhoId;
                    ));
        }
        update accounts;
    }
}

You do not need to check the Trigger.isAfter and Trigger.isUpdate as that filtering is already done because of the after insert, after update in the trigger signature. And update of the modified Accounts is needed because that is a different object than the trigger is operating on, but there is no need to query the Account you can just set the ID and update.

PS

You can add in logic related to the WhoId by making use of the getSObjectType and newSObject methods to create the correct type:

trigger UpdateDescriptions on Task (after insert, after update) {
    Map<Id, Task> m = new Map<Id, Task>();
    for (Task t : Trigger.new) {
        if (t.AccountId != null) m.put(t.AccountId, t);
        if (t.WhoId != null) m.put(t.WhoId, t)
    }
    if (m.size() > 0) {
        SObjects[] sobs = new SObject[] {};
        for (Id id : m.keySet()) {
            Task t = m.get(id);
            SObject sob = id.getSObjectType().newSObject(id);
            sob.put('Recent_Activity_Notes__c', t.Description);
            sob.put('Recent_Activity_Date__c, t.CreatedDate);
            sob.put('Recent_Activity_Owner__c, t.WhoId);
            sobs.add(sob);
        }
        update sobs;
    }
}
2
  • This worked perfect! Is there a way to do this for contacts & leads. I'm running into an error when trying to create based on WhoId Commented Dec 1, 2014 at 21:47
  • @AndrewSims See the PS. Not sure what owner you want for the contact/lead case though. You can alternatively use if/else logic based on the value returned by Id.getSObjectType() if that works better.
    – Keith C
    Commented Dec 1, 2014 at 22:05
0

Here you are getting the WHOID

Account acc = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Account WHERE Id = :t.WhoId ];

You need to be getting the AccountID

Account acc = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Account WHERE Id = :t.AccountId ];

Or more appropriate the WhatID

Account acc = [SELECT Id, Recent_Activity_Notes__c, Recent_Activity_Date__c, Recent_Activity_Owner__c From Account WHERE Id = :t.WhatId ];

Also, your comment

//We need to update associated Opportunity Fields with Fields from Case

Does not make sense as you are updating the account. Are you sure the code is doing what you want it to?

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .