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
SeanCenoSeanCeno 

Fields won't populate after sandbox refresh

I did a sandbox refresh today and before I did it, my fields were populating just fine (in the test environment) and now they aren't. All the classes were backed up and now recreated and I can't seem to find anything wrong with the code. The code saves fine, and has 98% coverage. This field population problem requires some triggers, a schedulable class, a batchable class, a test class, and then the Contact_RollupTrades Class itself. If you need these other pieces of code I can provide them. Please have a look at this code and see if you can find anything wrong with it.

 

public class Contact_RollupTrades {
    public Contact[] contactOldList { set; get; }
    public Contact[] contactNewList { set; get; }
    public Contact_Setting__c setting { set; get; }
    
    public Contact_RollupTrades(Contact[] contactOldList, Contact[] contactNewList) {
        this.contactOldList = contactOldList == null ? new Contact[] {} : contactOldList.clone();
        this.contactNewList = contactNewList == null ? new Contact[] {} : contactNewList.clone();
  
        this.setting = Contact_Setting__c.getInstance();
        this.setting = setting == null ? new Contact_Setting__c() : setting;
    }
    
    public void execute() {
        if (setting.Disable_Contact_Rollup__c == true)
            return;
        
        Contact[] contactUpdateableList = new Contact[] {};
        
        for(Contact contactNew : contactNewList) {
            if (contactNew == null || contact.Id == null)
                continue;
            if (contactNew.Rollup_Trades__c != null)
                continue;
            contactUpdateableList.add(contactNew);
        }
        
        execute(contactUpdateableList);
    }
    
    public void execute(Contact[] contactList) {
        if (contactList == null || contactList.size() == 0)
            return;
        
        // Reset contacts
        Map<Id, Contact> contactListMap = new Map<Id, Contact>(contactList);
        
        for(Contact contact : contactList) {
            contact.Total_NIOR_I_Sales__c = 0;
            contact.Total_NIOR_I_Shares__c = 0;
            contact.YTD_NIOR_I_Sales__c = 0;
            contact.YTD_NIOR_I_Shares__c = 0;
            contact.QTD_NIOR_I_Sales__c = 0;
            contact.QTD_NIOR_I_Shares__c = 0;
            contact.MTD_NIOR_I_Sales__c = 0;
            contact.MTD_NIOR_I_Shares__c = 0;
            contact.PY_NIOR_I_Sales__c = 0;
            contact.PY_NIOR_I_Shares__c = 0;
            
            contact.Total_NS_REIT_Sales__c = 0;
            contact.Total_NS_REIT_Shares__c = 0;
            contact.YTD_NS_REIT_Sales__c = 0;
            contact.YTD_NS_REIT_Shares__c = 0;
            contact.QTD_NS_REIT_Sales__c = 0;
            contact.QTD_NS_REIT_Shares__c = 0;
            contact.MTD_NS_REIT_Sales__c = 0;
            contact.MTD_NS_REIT_Shares__c = 0;
            contact.PY_NS_REIT_Sales__c = 0;
            contact.PY_NS_REIT_Shares__c = 0;
            
            contact.Total_NS_HIT_Sales__c = 0;
            contact.Total_NS_HIT_Shares__c = 0;
            contact.YTD_NS_HIT_Sales__c = 0;
            contact.YTD_NS_HIT_Shares__c = 0;
            contact.QTD_NS_HIT_Sales__c = 0;
            contact.QTD_NS_HIT_Shares__c = 0;
            contact.MTD_NS_HIT_Sales__c = 0;
            contact.MTD_NS_HIT_Shares__c = 0;
            contact.PY_NS_HIT_Sales__c = 0;
            contact.PY_NS_HIT_Shares__c = 0;
            
            contact.Rollup_Trades__c = DateTime.now();
        }
        
        // Roll up the trades based on the Resolved Firm Trading ID field
        
        Trades__c[] tradesList = [
            select Dollar_Amount_of_the_transaction__c
                 , Fund_Number__c
                 , Number_of_Shares_of_the_transaction__c
				 , Resolved_Firm_Trading_ID__c
				 , Resolved_Firm_Trading_IDs__c
				 , Resolved_to_Rep_Trading_ID__c
                 , Trade_Date__c
              from Trades__c
             where Resolved_Firm_Trading_IDs__c in :contactList
               and Fund_Number__c in ('3910', '3911', '3912')       // NIOR I; NS REIT; NS HIT
               and Dollar_Amount_of_the_transaction__c != null      // prevents null pointers below
               and Number_of_Shares_of_the_transaction__c != null   // prevents null pointers below
               and Trade_Date__c != null                            // prevents null pointers below
               
               // Negative values are ignored for roll-up purposes
               and Dollar_Amount_of_the_transaction__c >= 0
               and Number_of_Shares_of_the_transaction__c >= 0
        ];
        
        
        // Nothing to do?
        if (tradesList.size() == 0)
            return;
        
        // Update contacts
        for(Trades__c trades : tradesList) {
            Contact account = contactListMap.get(trades.Resolved_Firm_Trading_IDs__c);
            
            if (account == null || trades == null || trades.Trade_Date__c == null)
                continue;
            else if ('3910'.equals(trades.Fund_Number__c))
                processFund_3910(account, trades);
            else if ('3911'.equals(trades.Fund_Number__c))
                processFund_3911(account, trades);
            else if ('3912'.equals(trades.Fund_Number__c))
                processFund_3912(account, trades);
        }
    }
    
    void processFund_3910(Contact contact, Trades__c trades) {
        system.assert(null != contact);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            contact.YTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.YTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            contact.QTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.QTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            contact.MTD_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.MTD_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            contact.PY_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.PY_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            contact.Total_NIOR_I_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.Total_NIOR_I_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }

    void processFund_3911(Contact contact, Trades__c trades) {
        system.assert(null != contact);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            contact.YTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.YTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            contact.QTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.QTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            contact.MTD_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.MTD_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            contact.PY_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.PY_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            contact.Total_NS_REIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.Total_NS_REIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }
    
    void processFund_3912(Contact contact, Trades__c trades) {
        system.assert(null != contact);
        system.assert(null != trades);
        system.assert(null != trades.Trade_Date__c);
        
        Boolean isYTD = (date.today().year() == trades.Trade_Date__c.year());
        Boolean isMTD = (date.today().month() == trades.Trade_Date__c.month()) && isYTD;
        Boolean isQTD = (((date.today().month() - 1) / 3) + 1) == (((trades.Trade_Date__c.month() - 1) / 3) + 1) && isYTD;
        Boolean isPY = ((date.today().year() - 1) == trades.Trade_Date__c.year());
        Boolean isTotal = true;
        
        // YTD
        if (isYTD) {
            contact.YTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.YTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // QTD
        if (isQTD) {
            contact.QTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.QTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // MTD
        if (isMTD) {
            contact.MTD_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.MTD_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isPY) {
            contact.PY_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.PY_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
        
        // 
        if (isTotal) {
            contact.Total_NS_HIT_Sales__c += trades.Dollar_Amount_of_the_transaction__c;
            contact.Total_NS_HIT_Shares__c += trades.Number_of_Shares_of_the_transaction__c;
        }
    }
}

 I create a new trade, and it's not populating in the Contact, but it will populate in the National Accounts page which is the source of the code I used for the Contact page.

Suresh RaghuramSuresh Raghuram
after doing the sandbox refresh you will lose all the date you created in the sandbox. check weather do u have all the data required or not. IF not recreate the records that suit to the desired output.

If this answers your question make this as a solution and give kudos plz.
Hengky IlawanHengky Ilawan

Hi,

 

Is the Contact_Setting__c a Custom Setting?

Could it be the reason because when refreshing a  sandbox (developer and configuration only), the data will not be copied over?

 

Regards,

Hengky

SeanCenoSeanCeno

Hi Hengky,

 

I thought that could've been the problem as well, but unfortunately it wasn't as the Contact_Setting__c was copied over from production. Disable_Contact_Rollup__c is also a custom check box field within that setting. I'm still not finding anything wrong with my code.

SeanCenoSeanCeno

Here is part of the Test code with the equations removed, it says 98% coverage so hopefully it's not what's wrong...

 

@IsTest
public class Contact_RollupTradesTest {
    public static Contact contactUpdate { set; get; }
    
    public static final String FUND_NUMBER_NIOR_I = '3910';
    public static final String FUND_NUMBER_NS_REIT = '3911';
    public static final String FUND_NUMBER_NS_HIT = '3912';
    
    public static void test(String fundNumber, Date tradeDate, Decimal totalAmount, Decimal totalShares) {
        // Force tests to run
        
        if (Contact_Setting__c.getInstance() == null)
  		upsert new Contact_Setting__c (SetupOwnerId=UserInfo.getOrganizationId());
        
        Contact_Setting__c setting = Contact_Setting__c.getInstance();
        setting = setting == null ? new Contact_Setting__c() : setting;
        setting.Disable_Contact_Rollup__c = false;
        upsert setting;
		
	Account acc = new Account(Name= 'test');
	insert acc;
		
	contactUpdate = new Contact (Accountid = acc.id, LastName = 'TestLastName');
        insert contactUpdate;
		
        Account accountLocal = new Account();
        accountLocal.Name = 'Local Account';
        accountLocal.ParentId = accountLocal.Id;
        insert accountLocal;
        
        Contact contact = new Contact();
        contact.FirstName = 'FirstName';
        contact.LastName = 'LastName';
        contact.AccountId = accountLocal.Id;
        insert contact;
        
        Trades__c trades = new Trades__c();
        trades.Fund_Number__c = fundNumber;
        trades.Number_of_Shares_of_the_transaction__c = totalShares;
        trades.Dollar_Amount_of_the_transaction__c = totalAmount;
        trades.Trade_Date__c = tradeDate;
        trades.Posting_Date__c = tradeDate;
        trades.Resolved_to_Rep_Trading_ID__c = contact.Id;
        trades.Resolved_Office_Trading_ID__c = accountLocal.Id;
        trades.Resolved_Firm_Trading_IDs__c = contactUpdate.Id;
        insert trades;
    }
    









    @IsTest
    public static void testGovernorLimits() {
        // Force tests to run
        Account_Setting__c setting = Account_Setting__c.getInstance();
        setting = setting == null ? new Account_Setting__c() : setting;
        setting.Disable_RollupTrades__c = false;
        upsert setting;
        
        Account[] accountList = new Account[] {};
        
        for(Integer i = 0; i < 20; i++) {
            Account account = new Account();
            account.Name = 'National Account';
            accountList.add(account);
            
        }
        
        insert accountList;
        
        Contact[] contactList = new Contact[] {};
            
        for(Integer i = 0; i < 20; i++) {
            Contact contact = new Contact();
            contact.FirstName = 'FirstName';
            contact.LastName = 'LastName';
            contact.AccountId = accountList[i].Id;
            contactList.add(contact);
        }
        
        insert contactList;
        
        // Trades
        Trades__c[] tradesInsertList = new Trades__c[] {};
        Integer MAX_COUNT = 500;
        
        for(Integer i = 0; i < MAX_COUNT; i++) {
            // Random account
            Integer index = math.floor(math.random() * 20).intValue();
            
            Trades__c trades = new Trades__c();
            trades.Fund_Number__c = FUND_NUMBER_NIOR_I;
            trades.Number_of_Shares_of_the_transaction__c = 10.0;
            trades.Dollar_Amount_of_the_transaction__c = 100.0;
            trades.Trade_Date__c = date.today();
            trades.Posting_Date__c = date.today();
            trades.Resolved_to_Rep_Trading_ID__c = contactList[index].Id;
            trades.Resolved_Office_Trading_ID__c = null;
            trades.Resolved_Firm_Trading_ID__c = accountList[index].Id;
            tradesInsertList.add(trades);
        }
        
        Test.startTest();
        insert tradesInsertList;
        Test.stopTest();
    }
 
    public static Contact reselect(Contact contact) {
        return [
            select Name
                 , Total_NIOR_I_Sales__c
                 , Total_NIOR_I_Shares__c
                 , YTD_NIOR_I_Sales__c
                 , YTD_NIOR_I_Shares__c
                 , QTD_NIOR_I_Sales__c
                 , QTD_NIOR_I_Shares__c
                 , MTD_NIOR_I_Sales__c
                 , MTD_NIOR_I_Shares__c
                 , PY_NIOR_I_Sales__c
                 , PY_NIOR_I_Shares__c
                
                 , Total_NS_REIT_Sales__c
                 , Total_NS_REIT_Shares__c
                 , YTD_NS_REIT_Sales__c
                 , YTD_NS_REIT_Shares__c
                 , QTD_NS_REIT_Sales__c
                 , QTD_NS_REIT_Shares__c
                 , MTD_NS_REIT_Sales__c
                 , MTD_NS_REIT_Shares__c
                 , PY_NS_REIT_Sales__c
                 , PY_NS_REIT_Shares__c
                
                 , Total_NS_HIT_Sales__c
                 , Total_NS_HIT_Shares__c
                 , YTD_NS_HIT_Sales__c
                 , YTD_NS_HIT_Shares__c
                 , QTD_NS_HIT_Sales__c
                 , QTD_NS_HIT_Shares__c
                 , MTD_NS_HIT_Sales__c
                 , MTD_NS_HIT_Shares__c
                 , PY_NS_HIT_Sales__c
                 , PY_NS_HIT_Shares__c
              from Contact
             where Id = :contact.Id
             limit 1
        ];
    }
}

 

Hengky IlawanHengky Ilawan
Hi,

Could you post your trigger as well?
Thanks.
SeanCenoSeanCeno

Definitely.

 

Trigger for Contact_RollupTrades:

trigger Contact_RollupTrades on Contact (before update) {
  new Contact_RollupTrades(trigger.old, trigger.new).execute();
}

Trades_CascadeContacts Class:

public class Trades_CascadeContacts {
    public Trades__c[] tradesOldList { set; get; }
    public Trades__c[] tradesNewList { set; get; }
    public Map<Id, Trades__c> tradesOldListMap { set; get; }
    
    public Trades_CascadeContacts(Trades__c[] tradesOldList, Trades__c[] tradesNewList) {
        this.tradesNewList = tradesNewList == null ? new Trades__c[] {} : tradesNewList.clone();
        this.tradesOldList = tradesOldList == null ? new Trades__c[] {} : tradesOldList.clone();
        this.tradesOldListMap = new Map<Id, Trades__c>(this.tradesOldList);
    }
    
    public void execute() {
        Set<Id> tradesContactIds = new Set<Id> {};
        
        for(Trades__c tradesNew : tradesNewList) {
            Trades__c tradesOld = tradesOldListMap.get(tradesNew.Id);
            tradesOld = tradesOld == null ? new Trades__c() : tradesOld;
            
            tradesContactIds.add(tradesOld.Resolved_Firm_Trading_IDs__c);
            tradesContactIds.add(tradesNew.Resolved_Firm_Trading_IDs__c);
        }
        
        if (tradesContactIds.size() == 0)
            return;
        
        Contact[] contactList = new Contact[] {};
        
        for(Id contactId : tradesContactIds) {
            if (contactId == null)
                continue;
            
            Contact contact = new Contact(Id = contactId);
            contact.Rollup_Trades__c = null;
            contactList.add(contact);
        }
        
        update contactList;
    }
}




Trades_CascadeContacts Trigger:

trigger Trades_CascadeContacts on Trades__c (after delete, after insert, after undelete, after update) {
      Trades__c[] tradesOldList = trigger.IsDelete ? null : trigger.old;
        Trades__c[] tradesNewList = trigger.IsDelete ? trigger.old : trigger.new;
        new Trades_CascadeContacts(tradesOldList, tradesNewList).execute();

 

 

The Batchable and Schedulable Class:

 

global class Contact_RollupTradesBatchable implements Database.Batchable<sObject>, Database.Stateful {
    global Database.QueryLocator start(Database.BatchableContext batchableContext){
        return Database.getQueryLocator('select Id from Contact where ReportsToId = null'); //ParentId failed in production; use workbench to use correct metadata
    }
    
    global void execute(Database.BatchableContext batchableContext, Contact[] contactList) {
        for(Contact contact : contactList)
            contact.Rollup_Trades__c = null;
              update contactList;
    }
    global void finish(Database.BatchableContext batchableContext) {
        
    }
}



global class Contact_RollupTradesSchedulable implements Schedulable {
    global void execute(SchedulableContext schedulableContext) {
        Database.executeBatch(new Contact_RollupTradesBatchable(), 10);
    }
}

 Let me know if you need anything else. The trigger is brief, but it worked before and it follows the same format as the Account_RollupTrades

kibitzerkibitzer

Could you try looking at the debug logs and verifying the operation of GetInstance on the custom setting?

 

I'm seeing a case where even though the custom setting is present (when using manage custom settings), GetInstance returns null after a sandbox refresh.  I know of at least one other person who is seeing this issue as well.

 

Dan