0
votes

I cant figure out why this trigger is sometimes updating records that dont match the criteria. The idea is that when an account goes from 'on-hold' to an active service, any cancelled assignments are returned to pending. I cant figure out whats triggering it, but it seems everyone in a while, assignments are un-cancelled for accounts that have no change in service. Heres the code:

trigger cancelAssignments on Account (before update) {
    List<Assignment__c> masterListA = [select Id, Status__c, Practice__c from Assignment__c where Practice__c IN :Trigger.newMap.keySet() and type_of_work__c != 'a0Qa000000G1WmVEAV' AND (status__c = 'Feedback Needed' OR status__c = 'Pending Review' OR status__c = 'Accepted')];    
    List<Assignment__c> masterListB = [select Id, Status__c, Practice__c from Assignment__c where Practice__c IN :Trigger.newMap.keySet() and type_of_work__c != 'a0Qa000000G1WmVEAV' AND (status__c = 'Canceled')]; 

    for (Account oAccount : trigger.new) {
        if (oAccount.current_services__c == null || oAccount.current_services__c == 'Hold'){
            for (Account oAcct : trigger.old){
                if (oAcct.current_services__c != null && oAcct.current_services__c != 'Hold'){
                    List<Assignment__c> assignmentsToUpdate = new List<Assignment__c>();
                    for (Assignment__c rd : masterListA){
                        if (rd.practice__c == oAccount.id){
                        rd.Status__c = 'Canceled';
                        assignmentsToUpdate.add(rd); 
                    }
                    }update assignmentsToUpdate;
                }
            }
        }
        else if (oAccount.current_services__c != 'Hold' && oAccount.current_services__c != null  ){
            for (Account oAcctB : trigger.old){
                if (oAcctB.current_services__c == 'Hold'){
                    List<Assignment__c> assignmentsToUpdateB = new List<Assignment__c>();
                    for (Assignment__c rdB : masterListB){
                        if (rdB.practice__c == oAccount.id){
                        rdB.Status__c = 'Pending Review';
                        assignmentsToUpdateB.add(rdB); 
                    }
                    }update assignmentsToUpdateB;
                }
            }    
        }
    }
}
2
Have you checked for any validation rules or workflow rules that might be affecting the results? - Matt Lacey

2 Answers

0
votes

The problem may be as follows:

  • masterListB grabs assignments for more than one account
  • The code in the for (Account oAcctB : trigger.old) loop never checks to see whether old account that's in "Hold" status is the same account

One solution may be to make the edit below:

/* Old condition replaced:
   if (oAcctB.current_services__c == 'Hold') { */

if (oAcctB.current_services__c == 'Hold' and oAcctB.Id == oAccount.Id) {

To prove whether this is the right solution, I suggest creating a unit test that works like this:

  1. Create two Accounts, "Alpha Corp" and "Beta Corp"
  2. Set Alpha Corp's Current Services to "Hold"
  3. Set Beta Corp's Current Services to "Active"
  4. Add a related Assignment to Alpha Corp with Status "Canceled"
  5. Add a related Assignment to Beta Corp with Status "Canceled"
  6. Update both accounts in a single DML operation, doing something trivial like changing the Billing Country from "US" to "United States"
  7. Assert that the related Assignment for Alpha Corp remains "Canceled"

I suspect that the code you shared will not pass the unit test, in which case you'll be able to zero in on the problem and fix it.

0
votes

While Marty's code answered the question I asked, I also ran into some 'Too Many Code Statements' errors. Here is the final code that seems to resolve that:

trigger cancelAssignments on Account (before update) {
List<account> quitingAccounts = new List<account>();
List<account> returningAccounts = new List<account>();
List<Assignment__c> assignmentsToCancel;
List<Assignment__c> assignmentsToReturn;
for (Account oAccount : trigger.new)
    {
    if (oAccount.current_services__c == null || oAccount.current_services__c == 'Hold')
        {
        for (Account oAcct : trigger.old)
            {
            if (oAcct.current_services__c != null && oAcct.current_services__c != 'Hold' && oAcct.Id == oAccount.Id)
                {                    
                quitingAccounts.add(oAcct);                                      
                }
            }
        }
    else if (oAccount.current_services__c != 'Hold' && oAccount.current_services__c != null  )
        {
        for (Account oAcctB : trigger.old)
            {
            if (oAcctB.current_services__c == 'Hold'  && oAcctB.Id == oAccount.Id)
                {
                returningAccounts.add(oAcctB);
                }
            }    
        }
    }        
assignmentsToCancel = [select Id, Status__c, Practice__c from Assignment__c  where Practice__c IN :quitingAccounts and type_of_work__c != 'a0Qa000000G1WmVEAV' AND (status__c = 'Feedback Needed' OR status__c = 'Pending Review' OR status__c = 'Accepted')];
assignmentsToReturn = [select Id, Status__c, Practice__c from Assignment__c  where Practice__c IN :returningAccounts and type_of_work__c != 'a0Qa000000G1WmVEAV' AND status__c = 'Canceled'];
for (Assignment__c rd : assignmentsToCancel)
    {
    rd.Status__c = 'Canceled';
    }
for (Assignment__c rd : assignmentsToReturn)
    {
    rd.Status__c = 'Pending Review';
    }
update assignmentsToCancel;
update assignmentsToReturn;

}