Apex Clear all fields for a SObject record

The clearOutRecords would iterate all the fields passed as the currentRecord, then:
1. Exclude the fields as part of the fieldsToExcludeForClearOut Set and relationship fields
2. Check if the field is not null and updateable
3. Special logic to set fields to predefined values
4. Set all other fields to null
5. Return the SObject with fields as null


private static Set<String> fieldsToExcludeForClearOut = new Set<String>{'Cases', 'DoNotCall', 
'HasOptedOutOfFax', 'HasOptedOutOfEmail', 'LastName', 
'FirstName', 'Email', 'AccountId', 'CreatedDate',
'IsDeleted','Interval__c','OwnerId',
'OtherGeocodeAccuracy','MailingGeocodeAccuracy',
'BillingGeocodeAccuracy','ShippingGeocodeAccuracy'};

    public SObject clearOutRecords(SObject currentRecord, String sObjectName){
      SObjectType objToken = Schema.getGlobalDescribe().get(sObjectName);
      DescribeSObjectResult objDef = objToken.getDescribe();
      Map<String, SObjectField> fieldsSobject = objDef.fields.getMap();
      Map<String, Object> fields = currentRecord.getPopulatedFieldsAsMap();
      Type classType = Type.forName(sObjectName);
      SObject mergedRecord = (SObject)JSON.deserialize('{}', classType);
      for (String field : fields.keySet()){
        if (!fieldsToExcludeForClearOut.contains(field) && !field.contains('__r')){
          if (currentRecord.get(field)!=null && fieldsSobject.get(field).getDescribe().isUpdateable()){
            if ('User_Status__c'.equals(field)){
              mergedRecord.put(field, 'Incomplete');
            } else if ('Is_Mail_Same_As_Home__c'.equals(field)){
              mergedRecord.put(field, false);
            } else {
              mergedRecord.put(field, null);
            }
            } else if ('Id'.equals(field)){
            mergedRecord.put(field, currentRecord.get(field));
          }
        }
      }
      return mergedRecord;
    }

Initializing the clearOutRecords method

1. Query the fields that you would like to clear
2. Pass the Object to the clearOutRecords method

Contact queryContact = [Select Id, FirstName, LastName, Email, Birthdate, MailingState, Age__c from Contact where MailingState!=null limit 1 ];

Contact clearedOutContact = (Contact)App_Service.instance.clearOutRecords(queryContact, 'Contact');
        

Output

Contact:{Id=0036300000TQZIwAAP, Birthdate=null, MailingState=null}

Apex Comparator compare multiple object fields

Sorting a list of Analysis messages first by boolean and then integer. First we will order by condition and then order. All records where condition is true is will be on top in descending order on top followed by all false condition in descending order.

SummaryAnalysisMessages object to sort

public class SummaryAnalysisMessages {
		private String title;
		private String description;
		private Integer order;
		private Boolean condition;

		public SummaryAnalysisMessages(String title, String description, Integer order, Boolean condition){
			this.title = title;
			this.description = description;
			this.order = order;
			this.condition = condition;
		}

		public Boolean getCondition(){
			return condition;
		}

		public Integer getOrder(){
			return order;
		}
	}

Compare object by condition and then order

public class SummaryAnalysisMessagesCompare extends App_Comparator {
    public override Integer compare(Object a, Object b) {
			SummaryAnalysisMessages aSummaryMessage = (SummaryAnalysisMessages)a;
			SummaryAnalysisMessages bSummaryMessage = (SummaryAnalysisMessages)b;

      Integer summaryMessage1 = aSummaryMessage.getCondition() ? 1 : 0;
      Integer summaryMessage2 = bSummaryMessage.getCondition() ? 1 : 0;

			Integer compareInt = summaryMessage2 - summaryMessage1;
      if (compareInt == 0) {
          compareInt = aSummaryMessage.getOrder() - bSummaryMessage.getOrder();
      }
      return compareInt;
    }
}

Test class to test order

@isTest static void testSummaryAnalysisMessagesCompare(){
		SummaryAnalysisMessages summaryAnalysisMessage1 = new App_Chart.SummaryAnalysisMessages('1', '', 1, false);
		SummaryAnalysisMessages summaryAnalysisMessage2 = new App_Chart.SummaryAnalysisMessages('2', '', 2, true);
		SummaryAnalysisMessages summaryAnalysisMessage3 = new App_Chart.SummaryAnalysisMessages('3', '', 3, false);
		SummaryAnalysisMessages summaryAnalysisMessage4 = new App_Chart.SummaryAnalysisMessages('4', '', 4, true);

		List<SummaryAnalysisMessages> assetAllocationSummaryList = new List<SummaryAnalysisMessages>{summaryAnalysisMessage1, summaryAnalysisMessage2, summaryAnalysisMessage3, summaryAnalysisMessage4};

		App_Comparator.sort(assetAllocationSummaryList, new App_Chart.SummaryAnalysisMessagesCompare());
		System.assertEquals(assetAllocationSummaryList.get(0).getOrder(), 2);
		System.assertEquals(assetAllocationSummaryList.get(1).getOrder(), 4);
		System.assertEquals(assetAllocationSummaryList.get(2).getOrder(), 1);
		System.assertEquals(assetAllocationSummaryList.get(3).getOrder(), 3);
	}

Apex Return Diff fields between records

Sometimes you want to determine what has changed between an existing record in the database and an update to the record. The diffRecord method will return all the fields that changed for a specific record.

Compare the difference between to records and return changed fields

public SObject diffRecord(SObject updatedRecord, SObject currentRecord, String sObjectName){
  SObjectType objToken = Schema.getGlobalDescribe().get(sObjectName);
  DescribeSObjectResult objDef = objToken.getDescribe();
  Map<String, SObjectField> fields = objDef.fields.getMap();
  Type classType = Type.forName(sObjectName);
  SObject diffRecord = (SObject)JSON.deserialize('{}', classType);
  for (String field : fields.keySet()){
    if (!fieldsToExclude.contains(fields.get(field).getDescribe().getName()) && (fields.get(field).getDescribe().isUpdateable() || fields.get(field).getDescribe().isCreateable())){
        if (updatedRecord.get(field)!=currentRecord.get(field))
        	diffRecord.put(field, updatedRecord.get(field));
    }
  }
  return diffRecord;
}

Test that only changed fields are returned

@isTest static void testDiffRecords(){
  String currentRecordJSON = '{"Id":"a0L63000000qc43EAA","Account_Type__c":"Managed","Amount__c":50.00,"Category__c":"Deposit","Description__c":"Deposit","End_Date__c":"2020-03-31T15:06:57.000+0000","Frequency__c":"Monthly"}';
  String updatedRecordJSON = '{"Amount__c":50.0,"Id":"a0L63000000qc43EAA","Frequency__c":"Annually"}';
  Type classType = Type.forName('Account');
  SObject currentRecord = (SObject)JSON.deserialize(currentRecordJSON, classType);
  SObject updatedRecord = (SObject)JSON.deserialize(updatedRecordJSON, classType);
  Test.startTest();
    SObject diffRecord = App_Service.instance.diffRecord(updatedRecord, currentRecord, 'Account');
    System.assertEquals(diffRecord.get('Amount__c'), null);
    System.assertEquals(diffRecord.get('Frequency__c'), 'Annually');
    System.assertEquals(diffRecord.get('Account_Type__c'), null);
    System.assertEquals(diffRecord.get('Category__c'), null);
  Test.stopTest();
}

Apex Compare two Records and Merge updated fields

When you have two record, one being the existing queried record and the other the updated record. To merge the original with the updated field without committing the changes you can iterate the current record’s fields and check which of the fields changed. Update the changed fields to the new updated fields value. Now we have an merged record. Here is how I went about doing it.

Original SObject record

{"Account_Type__c":"Managed","Amount__c":50.00,"Category__c":"Deposit",
"Description__c":"Deposit","End_Date__c":"2020-03-31T15:06:57.000+0000",
"Frequency__c":"Monthly"}

Update SObject record

{"Amount__c":500.0,"Id":"a0L63000000qc43EAA","Frequency__c":"Annually"}

Merge two records with changes

private static Set<String> fieldsToExclude = new Set<String>{'OwnerId','OtherGeocodeAccuracy','MailingGeocodeAccuracy','BillingGeocodeAccuracy','ShippingGeocodeAccuracy'};
public SObject mergeRecords(SObject updatedRecord, SObject currentRecord, String sObjectName){
  SObjectType objToken = Schema.getGlobalDescribe().get(sObjectName);
  DescribeSObjectResult objDef = objToken.getDescribe();
  Map<String, SObjectField> fields = objDef.fields.getMap();
  Type classType = Type.forName(sObjectName);
  SObject mergedRecord = (SObject)JSON.deserialize('{}', classType);
  for (String field : fields.keySet()){
    if (!fieldsToExclude.contains(fields.get(field).getDescribe().getName()) && (fields.get(field).getDescribe().isUpdateable() || fields.get(field).getDescribe().isCreateable())){
        if (updatedRecord.get(field)!=null){
        	mergedRecord.put(field, updatedRecord.get(field));
    	} else if (currentRecord.get(field)!=null){
        	mergedRecord.put(field, currentRecord.get(field));
    	}
    }
  }
  return mergedRecord;
}

Test that fields were merged correctly

@isTest static void testMergeRecords(){
  String currentRecordJSON = '{"Id":"a0L63000000qc43EAA","Account_Type__c":"Managed","Amount__c":50.00,"Category__c":"Deposit","Description__c":"Deposit","End_Date__c":"2020-03-31T15:06:57.000+0000","Frequency__c":"Monthly"}';
  String updatedRecordJSON = '{"Amount__c":500.0,"Id":"a0L63000000qc43EAA","Frequency__c":"Annually"}';
  Type classType = Type.forName('Account');
  SObject currentRecord = (SObject)JSON.deserialize(currentRecordJSON, classType);
  SObject updatedRecord = (SObject)JSON.deserialize(updatedRecordJSON, classType);
  Test.startTest();
    SObject mergedRecord = mergeRecords(updatedRecord, currentRecord, 'Account');
    System.assertEquals(mergedRecord.get('Amount__c'), 500.0);
    System.assertEquals(mergedRecord.get('Frequency__c'), 'Annually');
    System.assertEquals(mergedRecord.get('Account_Type__c'), 'Managed');
    System.assertEquals(mergedRecord.get('Category__c'), 'Deposit');
  Test.stopTest();
}

List Salesforce Objects, Fields, References, Picklist Values using API in Java

package com.thysmichels;

import java.io.IOException;

import com.sforce.soap.partner.*;
import com.sforce.ws.*;

public class SalesforceGlobalSearch {
	
	/**
	 * @param args
	 * @throws IOException 
	 */
	public static void main(String[] args) throws IOException {
		// TODO Auto-generated method stub
		
		ConnectorConfig sfconfig = new ConnectorConfig();
		//Use your salesforce username = email
	    sfconfig.setUsername("username");
	    //Use your saleforce password with your security token look like: passwordjeIzBAQKkR6FBW8bw5HbVkkkk
	    sfconfig.setPassword("passwordsecuritytoken");
	 
	    PartnerConnection partnercon = null;
	    try {
	    	partnercon = Connector.newConnection(sfconfig);
	    	DescribeGlobalResult describeGlobalResult = partnercon.describeGlobal();
	    	DescribeGlobalSObjectResult[] sobjectResults = describeGlobalResult.getSobjects();
	    	if (describeGlobalResult != null)
	    	{
	    		//Object[] obj = describeGlobalResult.getSobjects();
	    		if (sobjectResults != null)
	    			for (int i = 0; i < sobjectResults.length; i++)
	    			{
	    				System.out.println("*** SObject: " + sobjectResults[i].getName() + " ***");     
	    				DescribeSObjectResult describeSObjectResult = partnercon.describeSObject(sobjectResults[i].getName());
	    				if (describeSObjectResult != null) 
	    				{
	    					Field[] fields = describeSObjectResult.getFields();
	    					PicklistEntry[] picklistValues;
	    					String[]referenceTos;
	    					for (int k = 0; k < fields.length; k++) 
	    					{
	    						System.out.println("Label: " + fields[k].getLabel() + " Name: " + fields[k].getName() + " Length: " + fields[k].getLength() + " Required Field: " + fields[k].getNillable());
	    						referenceTos = fields[k].getReferenceTo();
	    						if (referenceTos != null)
	    						{
	    							for (int j = 0; j < referenceTos.length; j++) 
	    							{
	    								System.out.println("Field Reference To: " + referenceTos[j]);
	    							}
	    						}
	    						picklistValues = fields[k].getPicklistValues();
	    						if (picklistValues != null) 
	    						{
	    							for (int j = 0; j < picklistValues.length; j++) 
	    							{
	    								if (picklistValues[j].getLabel() != null) 
	    								{
	    									System.out.println("\tItem: " + picklistValues[j].getLabel());
	    								}
	    							}
	    						}
	    					}
	    				}
	    			}
	    	} 
	    } catch (ConnectionException ce) {
	    	ce.printStackTrace();
	    }
	}
}

Output

*** SObject: Account ***
Label: Account ID Name: Id Length: 18 Required Field: false
Label: Deleted Name: IsDeleted Length: 0 Required Field: false
Label: Master Record ID Name: MasterRecordId Length: 18 Required Field: true
Field Reference To: Account
Label: Account Name Name: Name Length: 255 Required Field: false
Label: Account Type Name: Type Length: 40 Required Field: true
	Item: Prospect
	Item: Customer - Direct
	Item: Customer - Channel
	Item: Channel Partner / Reseller
	Item: Installation Partner
	Item: Technology Partner
	Item: Other
Label: Parent Account ID Name: ParentId Length: 18 Required Field: true
Field Reference To: Account