New Batch#100 (10th Nov 2021) - Salesforce Admin + Dev Training (WhatsApp: +91 - 8087988044) :https://t.co/p4F3oeQagK

Saturday, 27 February 2016

Sending an email notification to Admin whenever a field is created or deleted for a custom object in salesforce

S.No Component
1 Create New Object
Singular Label: ObjectsExistingFieldsInfo
Plural Label: ObjectsExistingFieldsInfos
Object Name: ObjectsExistingFieldsInfo
Standard Field
Field Label: ObjectsExistingFieldsInfo
Data Type: Auto Number
Display Format: ObjInfo-{000}
2 Create New Field
Object Name: ObjectsExistingFieldsInfo
Field Label: Field API Name
Field Name: Field_API_Name
Data Type: Text (255)
3 Create New Field
Object Name: ObjectsExistingFieldsInfo
Field Label: Fields Count
Field Name: Fields_Count
Data Type: Number (18,0)
4 Create New Field
Object Name: ObjectsExistingFieldsInfo
Field Label: Fields Info
Field Name: Fields_Info
Data Type: Long Text Area
global class FieldsValidator implements Database.Batchable<Sobject> {
global Database.queryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('select name, fields_info__c, fields_count__c from ObjectsExistingFieldsInfo__c');
}
global void execute(Database.BatchableContext bc, List<SObject> sobjLst) {
String[] types = new String[]{'Account','Contact'};
String emailBody = '';
// Make the describe call
Schema.DescribeSobjectResult[] results = Schema.describeSObjects(types);
Map<String,List<Field>> objFieldsDesMap = new Map<String,List<Field>>();
// For each returned result, get some info
for(Schema.DescribeSobjectResult res : results) {
Map<String, Schema.SObjectField> objectFields = res.fields.getMap();
for(Schema.SObjectField fDes : objectFields.values()) {
if(fDes.getDescribe().isCustom()) {
system.debug(fDes.getDescribe().getName()+'@@@'+fDes.getDescribe().getType());
String fieldAPIName = String.valueOf(fDes.getDescribe().getName());
String fieldDataType = String.valueOf(fDes.getDescribe().getType());
if(objFieldsDesMap.containsKey(res.getName())) {
objFieldsDesMap.get(res.getName()).add(new Field(fieldAPIName,fieldDataType));
}
else {
objFieldsDesMap.put(res.getName(),new List<Field>{new Field(fieldAPIName,fieldDataType)});
}
}
}
}
Map<String, ObjectsExistingFieldsInfo__c> objectInfoMap = new Map<String, ObjectsExistingFieldsInfo__c>();
for(ObjectsExistingFieldsInfo__c objInfo : [select Field_API_Name__c , Fields_Count__c, Fields_Info__c from
ObjectsExistingFieldsInfo__c where Field_API_Name__c in: types]) {
objectInfoMap.put(objInfo.Field_API_Name__c,objInfo);
}
for(String type : types) {
if(objectInfoMap.get(type).fields_count__c == null) {
objectInfoMap.get(type).fields_count__c = objFieldsDesMap.get(type).size();
objectInfoMap.get(type).fields_info__c = JSON.serialize(objFieldsDesMap.get(type));
}
else {
System.debug('entering to else condition...');
System.debug('entering to for loop..');
List<Field> exstingFields = new List<Field>();
List<Field> newFields = new List<Field>();
Map<String,Field> bkupexstingFields = new Map<String,Field>();
Map<String,Field> bkupnewFields = new Map<String,Field>();
exstingFields = (List<Field>)JSON.deserialize(objectInfoMap.get(type).fields_info__c, List<Field>.class);
System.debug('exstingFields: '+exstingFields);
newFields.addAll(objFieldsDesMap.get(type));
System.debug('objFieldsDesMap: '+objFieldsDesMap);
System.debug('newFields: '+newFields);
for(Field f : exstingFields) {
bkupexstingFields.put(f.apiName,f);
}
for(Field f : newFields) {
bkupnewFields.put(f.apiName,f);
}
for(Field f : exstingFields) {
bkupnewFields.remove(f.apiName);
}
for(Field f : newFields) {
bkupexstingFields.remove(f.apiName);
}
System.debug(bkupnewFields+'@@@'+bkupexstingFields);
emailBody += type + ' : ';
//for new fields
for(Field f :bkupnewFields.values()) {
emailBody += f.apiName + ' with datatype '+f.dataType+' is newly created.';
}
objectInfoMap.get(type).fields_count__c = objFieldsDesMap.get(type).size();
objectInfoMap.get(type).fields_info__c = JSON.serialize(objFieldsDesMap.get(type));
}
}
/*** Sending Email ***/
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(new List<String>{system.label.Dev_Admin});
mail.setSubject('Fields Update');
mail.setPlainTextBody(emailBody);
update objectInfoMap.values();
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{mail});
}
global void finish(Database.BatchableContext bc) {
}
public class Field {
String apiName, dataType;
public Field(String apiName, String dataType) {
this.apiName = apiName;
this.dataType = dataType;
}
}
}
view raw FieldsValidator hosted with ❤ by GitHub
Notes-
  • We cannot create trigger on 'Object' or 'Field'.
  • Alternative is creating a Batch Class and schedule it as per the requirement.
  • To store the history of the fields we can user either list custom settings or custom object.
  • List Custom Settings is not supporting Text Area Long.
  • To store the history of the fields we need Text Area Long (255 character for text area data type is not sufficient.) field which is possible with the custom object.

8 comments:

  1. I had executed above code in my developer instance without any errors but i didn't get mail notification when field is create and field is delete.. please help me

    ReplyDelete
    Replies
    1. 1. Please populate your email address in 'system.label.Dev_Admin'.
      2. Execute once (you don't receive email).
      3. 2nd time please create/delete a field and execute one more time.
      4. If your email address is valid you should get an email.

      Delete
    2. This comment has been removed by the author.

      Delete
    3. I populated my email even then I didn't receive any email. How is this batch apex getting triggered first of all?

      Delete
  2. Great work. good scenario ... thank you very much.

    ReplyDelete
  3. your post vry helpful i m fresher
    when i m trying this code i m getting this errorError "Error: Compile Error: unexpected token: '@' at line 74 column 52" actually i m replced mailid in place of "system.label.Dev_Admin" if i did not replace i m getting this error "Error Error: Compile Error: Invalid external string name: dev_admin at line 74 column 46
    "

    ReplyDelete
  4. please i m waiting your response i hope i will get ASAP
    THANK YOU

    ReplyDelete


  5. Hai Author, Very Good informative blog post,
    Thanks for Sharing

    ReplyDelete