• Athanasios "Sakis" Stergioulas
  • NEWBIE
  • 0 Points
  • Member since 2014


  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 1
    Questions
  • 4
    Replies
We would like to get some triggers launched live to our Salesforce based on a Class but keep running across several issues. To give a background of what we are trying to do is build a class that will run with the nonprofit starter pack Trigger configuration. That being said we have two classes, one for the Account and the other for the Contact, that syncronize specific fields so they are the same whenever a contact is being updated or an Account. Those classes work perfectly to fire off the triggers. When I try and deploy the code to the live version I get an error that says : 

ContactTriggerTest.ContactTriggerTest(), Details: System.AssertException: Assertion Failed: Expected: (false, null, 005i00000037r56AAA), Actual: (false, null, 005i00000037r56AAA) Class.ContactTriggerTest.ContactTriggerTest: line 35, column 1

I am sure you will need more specifics and I have added the code below for the Account class and Contact class. I have been stuck on this for some time now and any help would be grateful. Thank You.
global without sharing class AccountTriggerHandler extends npsp.TDTM_Runnable{

    
         // the main entry point for TDTM to invoke our trigger handlers.
        global override DmlWrapper run(List<SObject> listNew, List<SObject> listOld, 
            npsp.TDTM_Runnable.Action triggerAction, Schema.DescribeSObjectResult objResult) {

            List<String> fieldsToCheck = new List<String>{'Do_Not_Mail__c', 'OwnerId', 'RDO_Account_Flag__c'};

            Map<Id, Map<String, Object>> acctChangedFields = new Map<Id, Map<String,Object>>();
            List<Account> newAcctList = new List<Account>();
            List<Account> oldAcctList = new List<Account>();

            integer i = 0;  
            for (SObject so : listNew) { 
                Account acc = (Account)so;
                // BEFORE INSERT
                if (triggerAction == Action.BeforeInsert) {
                }
                // BEFORE UPDATE
                if (triggerAction == Action.BeforeUpdate) {

                }
                // AFTER INSERT
                if (triggerAction == Action.AfterInsert) {
                }
                // AFTER UPDATE
                if (triggerAction == Action.AfterUpdate) {
                    Account accNew = (Account) listnew[i];
                    Account accOld = (Account) listOld[i];
                
                    //populate account lists for our swapFields method
                    newAcctList.add(accNew);
                    oldAcctList.add(accOld);

                    // if field has changed
                    Map<String,Object> changedFields = hasFieldChanged(accNew, accOld, fieldsToCheck);
                    acctChangedFields.put(accNew.Id, changedFields);
                }

                i++;
            }

                //update contact fields (dml)
                if (acctChangedFields.size() > 0){
                    updateFields(acctChangedFields);
                   }

                //recursion prevention before DML operation
                if(checkRecursive.runOnce()){
                    swapFields(newAcctList,oldAcctList);
                }

            return null;
        }

        //checks if any of change-fields have changed
        private Map<String, Object> hasFieldChanged(Account acc, Account accOld, List<String> fieldsToCheck){
            Map<String, Object> changedFields = new Map<String, Object>();
            for(String fieldName: fieldsToCheck){
                if(acc.get(fieldName) != accOld.get(fieldName)){
                    changedFields.put(fieldName, acc.get(fieldName));
                    system.debug('putting in ' + fieldName + '=> ' + acc.get(fieldName));
                }
            }
            return changedFields;
        }

        //update account fields based on contact data
        private void updateFields(Map<Id, Map<String,Object>> acctChangedFields){
            List<Contact> accountContacts = [SELECT Id,AccountId FROM Contact WHERE AccountId IN :acctChangedFields.keyset()];        
            for(Contact con: accountContacts){
                for(String field: acctChangedFields.get(con.AccountId).keyset()){
                    system.debug('updating contact field ' + field + ' => ' + acctChangedFields.get(con.AccountId).get(field));
                    con.put(field,acctChangedFields.get(con.AccountId).get(field));
                }
            }
            update accountContacts;
        }
        

        // updatedAccount swaps fields with previously unupdated account
        private void swapFields(List<Account> updatedAccounts, List<Account> beforeUpdateAccounts){
            for(Integer i=0; i<=updatedAccounts.size(); i++){
                if((updatedAccounts[i].npe01__One2OneContact__c != beforeUpdateAccounts[i].npe01__One2OneContact__c)  && (updatedAccounts[i].npe01__One2OneContact__c == beforeUpdateAccounts[i].Secondary_Contact__c)){
                    updatedAccounts[i].Secondary_Contact__c =  beforeUpdateAccounts[i].npe01__One2OneContact__c;
                }
            }
        }
 
@isTest(SEEALLDATA=true)
private class AccountTriggerTest {
	
static testMethod void AccountTriggerTest() {
Account acc = new Account(Do_Not_Mail__c=true,name = 'Test First and Last Name',
							npo02__Formal_Greeting__c = 'Test First & Last Name',RDO_Account_Flag__c = 'Test Tier');
insert acc;

acc.Do_Not_Mail__c=false;
acc.RDO_Account_Flag__c = 'Test Tier 1';
acc.OwnerId = '005i00000037r56';

update acc;

 List<String> accStrings = new List<String>();
List<String> conStrings = new List<String>();

List<String> fields = new List<String> {'Do_Not_Mail__c', 'RDO_Account_Flag__c', 'OwnerId'};
		
		
		Account updatedAcc = [SELECT Id,Do_Not_Mail__c,RDO_Account_Flag__c, OwnerId
						FROM Account 
						WHERE npo02__Formal_Greeting__c = :acc.npo02__Formal_Greeting__c
						LIMIT 1];

		Contact updatedCon = [SELECT Id, Do_Not_Mail__c,RDO_Account_Flag__c 
								FROM Contact 
								WHERE OwnerId = :updatedAcc.OwnerId
								LIMIT 1];
		update updatedCon;

		for(String field: fields){
			accStrings.add(String.valueOf(updatedAcc.get(field)));
			conStrings.add(String.valueOf(updatedCon.get(field)));

		}

		system.assertEquals(conStrings, accStrings);
	}
}
global without sharing class ContactTriggerHandler extends npsp.TDTM_Runnable{
    
     // the main entry point for TDTM to invoke our trigger handlers.
    global override DmlWrapper run(List<SObject> listNew, List<SObject> listOld, 
        npsp.TDTM_Runnable.Action triggerAction, Schema.DescribeSObjectResult objResult) {

        Map<Id, Contact> updatedContacts = new Map<Id, Contact>(); 

        //list of fields that need to be checked on trigger update --> amend as necessary
        List<String> fieldsToCheck = new List<String> 
            {'Do_Not_Mail__c', 'OwnerId', 'RDO_Account_Flag__c'};

        integer i = 0;  
        for (SObject so : listNew) { 
            Contact con = (Contact)so;
            // BEFORE INSERT
            if (triggerAction == Action.BeforeInsert) {
            }
            // BEFORE UPDATE
            if (triggerAction == Action.BeforeUpdate) {
          
            }
            // AFTER INSERT
            if (triggerAction == Action.AfterInsert) {
            }
            // AFTER UPDATE
            if (triggerAction == Action.AfterUpdate) {
                Contact conNew = (Contact) listnew[i];
                Contact conOld = (Contact) listOld[i];

                // if field  has changed
                if (!trigger.isDelete && hasFieldChanged(conNew, conOld, fieldsToCheck)){
                    updatedContacts.put(conNew.AccountId, conNew);
                } 

            }
            i++;
        }

            if (updatedContacts.size() > 0){
                updateFields(updatedContacts, fieldsToCheck);
            }

        return null;
    }

    //checks if any of change-fields have changed
    private boolean hasFieldChanged(Contact con, Contact conOld, List<String> fieldsToCheck)
    {

        boolean change = false;

        for(String fieldName: fieldsToCheck){
            if(con.get(fieldName) != conOld.get(fieldName)){
                change = true;
            }
        }
        return change;
    }

    //update account fields based on contact data
    private void updateFields(Map<Id, Contact> updatedContacts, List<String> fieldsToCheck){

        List<Account> contactAccounts = [SELECT Id FROM Account WHERE Id IN :updatedContacts.keyset()];
        
        for(Account acc: contactAccounts){
            for(String field: fieldsToCheck){
                acc.put(field,updatedContacts.get(acc.Id).get(field));
            }
        }
        update contactAccounts;
    }
}
@isTest(SEEALLDATA=true)
private class ContactTriggerTest {

   static testMethod void ContactTriggerTest() {

		 contact c = new Contact(Do_Not_Mail__c=true,lastname = 'Test LastName',
		 						firstname = 'Test FirstName',RDO_Account_Flag__c = 'Test Tier', kw__City__c = 'aW67h5z9');
		 insert c;
		 c.Do_Not_Mail__c=false;
		 c.RDO_Account_Flag__c = 'Test Tier 1';
		 c.OwnerId = '005i00000037r56';

		 update c;

		 List<String> conStrings = new List<String>();
		 List<String> accStrings = new List<String>();

		 List<String> fields = new List<String> {'Do_Not_Mail__c', 'RDO_Account_Flag__c', 'OwnerId'};

		Contact updatedCon = [SELECT AccountId, Do_Not_Mail__c,RDO_Account_Flag__c,OwnerId 
								FROM Contact 
								WHERE kw__City__c = :c.kw__City__c
								LIMIT 1];

		Account updatedAcc = [SELECT Id,Do_Not_Mail__c,RDO_Account_Flag__c, OwnerId
						FROM Account 
						WHERE Id = :updatedCon.AccountId
						LIMIT 1];

		for(String field: fields){
			conStrings.add(String.valueOf(updatedCon.get(field)));
			accStrings.add(String.valueOf(updatedAcc.get(field)));
		}
        
		system.assertEquals(conStrings, accStrings);
	}
}
 
public without sharing class checkRecursive{
    private static boolean run = true;
    public static boolean runOnce(){
    	if(run){
     		run=false;
     		return true;
    	}
    	else{
        	return run;
    	}
    }
}


 
Has anyone completed this trail? I am stomped on challenge number 3, regarding created the process for fulfillment. Any pointers or guidance would be appreciated.