• Harjeet Singh 13
  • NEWBIE
  • 70 Points
  • Member since 2015

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 44
    Questions
  • 67
    Replies
I am developing a functionality where I need to copy emails(emails+attachments) from a child case to parent case on merging.
Right now what ever I have developed I achieved copying emails from child to master case. But when an email is sent with attachments from child case then only email is getting copied to master case not the attachments.
Below is my trigger code
 
trigger CaseTrigger on Case (before insert, after insert, before update,after update, before delete,after delete) {

    CaseTriggerHandler csHandler = new CaseTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate,trigger.isInsert);

    if (trigger.isAfter && trigger.isInsert) {

       csHandler.HandleAfterInsert();

    }
    if (trigger.isAfter && trigger.isUpdate) {

       csHandler.HandleAfterUpdate();

    }

}

And Below is my trigger handler class(I have kept only useful method related to my question,rest I have omitted for better view and usefulness to my question)
 
public class CaseTriggerHandler { 

    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }

    List<Case> listOfCase;
    List<Case> newCase;
    List<Case> oldCase;
    Map<Id,Case> newCaseMap;
    Map<Id,Case> oldCaseMap;
    boolean isUpdate;
    boolean isDelete;    

    public CaseTriggerHandler (List<Case> newCase, List<Case> oldCase, 
                               Map<Id,Case> newCaseMap, Map<Id,Case> oldCaseMap, boolean isUpdate, boolean isDelete){
                                   this.newCase = newCase;
                                   this.oldCase = oldCase;
                                   this.newCaseMap = newCaseMap;
                                   this.oldCaseMap = oldCaseMap;
                                   this.isUpdate = isUpdate;
                                   this.isDelete = isDelete;
                               }

    public void HandleAfterUpdate(){       
        if(run){     

            handleemailattachment();

        }
    }

    public void HandleAfterInsert(){

        handleemailattachment();

    } 

    public void handleemailattachment(){
     Map<Id, Id> parentCaseIdMap = new Map<Id, Id>();
     for(Case c : newCase){
         if(c.ParentId!=null)parentCaseIdMap.put(c.Id, c.ParentId);
     }
     // Fetch all the attachments related to the child case
     List<EmailMessage> EmailMessageList= new List<EmailMessage>();
     List<EmailMessage> attachmentToBeCloned = new List<EmailMessage>();
     EmailMessageList = [Select Id,Subject,ParentId,textBody From EmailMessage Where ParentId in:parentCaseIdMap.keySet()];
     for(EmailMessage att : EmailMessageList){
         EmailMessage a = att.clone();
         if(parentCaseIdMap.containsKey(att.ParentId)){
            a.ParentId = parentCaseIdMap.get(att.ParentId);
            attachmentToBeCloned.add(a); 
         } 
    }
    if(attachmentToBeCloned!=null && attachmentToBeCloned.size()>0){
        insert attachmentToBeCloned;
    } 
}
}

Illustration of my requirements:
Suppose I created one Email- to-Case which triggers a creation of cases in SF with 2 emails. Now I linked this case to other Case. Upon merging both of the cases emails are getting copied to master/parent case but if I attach any attachment while creating Email to Case then upon merging only emails are getting copied not attachments .

Kindly help.

Many thanks in advance

Thanks & Regards,
Harjeet
I am developing a functionality where I need to copy emails(emails+attachments) from a child case to parent case on merging.
Right now what ever I have developed I achieved copying emails from child to master case. But when an email is sent with attachments from child case then only email is getting copied to master case not the attachments.
Below is my trigger code
trigger CaseTrigger on Case (before insert, after insert, before update,after update, before delete,after delete) {

    CaseTriggerHandler csHandler = new CaseTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate,trigger.isInsert);

    if (trigger.isAfter && trigger.isInsert) {

       csHandler.HandleAfterInsert();

    }
    if (trigger.isAfter && trigger.isUpdate) {

       csHandler.HandleAfterUpdate();

    }

}

And Below is my trigger handler class(I have kept only useful method related to my question,rest I have omitted for better view and usefulness to my question)
public class CaseTriggerHandler { 

    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }

    List<Case> listOfCase;
    List<Case> newCase;
    List<Case> oldCase;
    Map<Id,Case> newCaseMap;
    Map<Id,Case> oldCaseMap;
    boolean isUpdate;
    boolean isDelete;    

    public CaseTriggerHandler (List<Case> newCase, List<Case> oldCase, 
                               Map<Id,Case> newCaseMap, Map<Id,Case> oldCaseMap, boolean isUpdate, boolean isDelete){
                                   this.newCase = newCase;
                                   this.oldCase = oldCase;
                                   this.newCaseMap = newCaseMap;
                                   this.oldCaseMap = oldCaseMap;
                                   this.isUpdate = isUpdate;
                                   this.isDelete = isDelete;
                               }

    public void HandleAfterUpdate(){       
        if(run){     

            handleemailattachment();

        }
    }

    public void HandleAfterInsert(){

        handleemailattachment();

    } 

    public void handleemailattachment(){
     Map<Id, Id> parentCaseIdMap = new Map<Id, Id>();
     for(Case c : newCase){
         if(c.ParentId!=null)parentCaseIdMap.put(c.Id, c.ParentId);
     }
     // Fetch all the attachments related to the child case
     List<EmailMessage> EmailMessageList= new List<EmailMessage>();
     List<EmailMessage> attachmentToBeCloned = new List<EmailMessage>();
     EmailMessageList = [Select Id,Subject,ParentId,textBody From EmailMessage Where ParentId in:parentCaseIdMap.keySet()];
     for(EmailMessage att : EmailMessageList){
         EmailMessage a = att.clone();
         if(parentCaseIdMap.containsKey(att.ParentId)){
            a.ParentId = parentCaseIdMap.get(att.ParentId);
            attachmentToBeCloned.add(a); 
         } 
    }
    if(attachmentToBeCloned!=null && attachmentToBeCloned.size()>0){
        insert attachmentToBeCloned;
    } 
}
}

Illustration of my requirements:
Suppose I created one Email- to-Case which triggers a creation of cases in SF with 2 emails. Now I linked this case to other Case. Upon merging both of the cases emails are getting copied to master/parent case but if I attach any attachment while creating Email to Case then upon merging only emails are getting copied not attachments .

Kindly help.

Many thanks in advance

Thanks & Regards,
Harjeet
I am currently working on a requirement where I need to notify account owner if some other person (Non Account Owner) Logs a Call against their account . Notification could be in form of a chatter message or email should be sent out to the account owner.

Kindly help to acheive above mentioned requirements.

Many thanks in advance

Thanks & Regards,
Harjeet
Dear All,

I have developed a class which is calling standard REST API to determine Daily Apex Exceution Limits. I am getting error when I am running test class for the same.

Below is my Apex Class:
 
public class CurrentStorage{


public static void getStorage() {

//fetch session od of user
String sid = Userinfo.getSessionId();

//fetch Instance URL
String baseURL = System.URL.getSalesforceBaseUrl().toExternalForm();
    
    
//Building call out to Standard Salesforce Rest API
HttpRequest req = new HttpRequest();

req.setMethod('GET');
req.setEndpoint(baseURL+'/services/data/v41.0/limits');
req.setHeader('Authorization', 'OAuth '+ sid);

Http http = new Http();
    
HTTPResponse res = http.send(req);

Map<String, Object> m = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());
Map<String, Object> dataStorage = (Map<String,Object>)m.get('DailyAsyncApexExecutions');
System.debug('Map: '+ dataStorage);
System.debug('Current Storage: ' + dataStorage.get('Remaining'));

If(Integer.valueof(dataStorage.get('Max'))*(0.8)<= (Integer.valueof(dataStorage.get('Max')) - Integer.valueof(dataStorage.get('Remaining')))){
    
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
                message.toAddresses = new String[] { 'abc@gmail.com','def@gmail.com'};
                //message.optOutPolicy = 'FILTER';
                message.subject = 'Async Apex Limits Threshold Warning';
                message.plainTextBody = 'Your Org Limit of Daily Async Apex Execution reached 80% threshold for '+ baseURL;
                Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage> {message};
                Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);

			if (results[0].success) 
			{
   				 System.debug('The email was sent successfully.');
			} else 
			{
    				System.debug('The email failed to send: ' + results[0].errors[0].message);
			}
         }
    
 
        
            // Send Mail to people
}

}

Below is my test class:
 
@isTest
public class TestCurrentStorage {
    
    static testMethod void validateLocationCallouts() {
    
         RestRequest req = new RestRequest(); 
        req.params.put('DailyAsyncApexExecutions', '250000');
        //req.params.put('Max', '250000');
        req.params.put('Remaining', '200000');
        
        Test.startTest();
   
    
           Test.setMock(HttpCalloutMock.class, new MockHttpResponse());

           CurrentStorage.getStorage();
          Test.stopTest();
    }
    


}

Below is my mock class:
 
@isTest
global class mockHttpResponse implements HttpCalloutMock{
    
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        System.assertEquals('GET', req.getMethod());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        
        res.setBody('{"Max": "250000","Remaining": "200000"}');
        res.setStatusCode(200);
        res.setStatus('OK');
        return res;
    }

}

When I am trying to run tess class I am getting below error trace logs:
 
Errors:
System.NullPointerException: Attempt to de-reference a null object


Stack Trace:
Class.CurrentStorage.getStorage:
Class.TestCurrentStorage.validateLocationCallouts:

Kindly help me to pass the test class and also test class showing 57% code coverage and singlemessaging code is not covering

Many thanks in advance

Thanks & Regards,
Harjeet​ ​​
Dear All,

I have developed a class which is calling standard REST API to determine Daily Apex Exceution Limits. I am getting error when I am running test class for the same.

Below is my Apex Class:
public class CurrentStorage{


public static void getStorage() {

//fetch session od of user
String sid = Userinfo.getSessionId();

//fetch Instance URL
String baseURL = System.URL.getSalesforceBaseUrl().toExternalForm();
    
    
//Building call out to Standard Salesforce Rest API
HttpRequest req = new HttpRequest();

req.setMethod('GET');
req.setEndpoint(baseURL+'/services/data/v41.0/limits');
req.setHeader('Authorization', 'OAuth '+ sid);

Http http = new Http();
    
HTTPResponse res = http.send(req);

Map<String, Object> m = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());
Map<String, Object> dataStorage = (Map<String,Object>)m.get('DailyAsyncApexExecutions');
System.debug('Map: '+ dataStorage);
System.debug('Current Storage: ' + dataStorage.get('Remaining'));

If(Integer.valueof(dataStorage.get('Max'))*(0.8)<= (Integer.valueof(dataStorage.get('Max')) - Integer.valueof(dataStorage.get('Remaining')))){
    
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
                message.toAddresses = new String[] { 'abc@gmail.com','def@gmail.com'};
                //message.optOutPolicy = 'FILTER';
                message.subject = 'Async Apex Limits Threshold Warning';
                message.plainTextBody = 'Your Org Limit of Daily Async Apex Execution reached 80% threshold for '+ baseURL;
                Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage> {message};
                Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);

			if (results[0].success) 
			{
   				 System.debug('The email was sent successfully.');
			} else 
			{
    				System.debug('The email failed to send: ' + results[0].errors[0].message);
			}
         }
    
 
        
            // Send Mail to people
}

}

Below is my test class:
 
@isTest
public class TestCurrentStorage {
    
    static testMethod void validateLocationCallouts() {
    
         RestRequest req = new RestRequest(); 
        req.params.put('DailyAsyncApexExecutions', '250000');
        //req.params.put('Max', '250000');
        req.params.put('Remaining', '200000');
        
        Test.startTest();
   
    
           Test.setMock(HttpCalloutMock.class, new MockHttpResponse());

           CurrentStorage.getStorage();
          Test.stopTest();
    }
    


}

Below is my mock class:
 
@isTest
global class mockHttpResponse implements HttpCalloutMock{
    
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        System.assertEquals('GET', req.getMethod());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        
        res.setBody('{"Max": "250000","Remaining": "200000"}');
        res.setStatusCode(200);
        res.setStatus('OK');
        return res;
    }

}

When I am trying to run tess class I am getting below error trace logs:
 
Errors:
System.NullPointerException: Attempt to de-reference a null object


Stack Trace:
Class.CurrentStorage.getStorage:
Class.TestCurrentStorage.validateLocationCallouts:

Kindly help me to pass the test class.

Many thanks in advance

Thanks & Regards,
Harjeet​ ​​
Dear All,

I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit(24hrs API Limit). Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then any alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.

I have done few research on the same but didn't get anything concrete. I saw blogs/documentation stating about Limit class and Limit methods but those are having limit method for future but no where I get any thing related to Async Apex Exceution Limits. In Limit Class I saw there are 2 mthods 'getAsyncCalls()' and 'getLimitAsyncCalls()' but both are related reserved for future use.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_limits.htm#apex_System_limits_getAsyncCalls
Kindly help me.

Any help will be greatly appreciated.

Many thanks in advance

Thanks & Regards,
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit(24hrs API Limit). Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then any alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.

I have done few research on the same but didn't get anything concrete. I saw blogs/documentation stating about Limit class and Limit methods but those are having limit method for future but no where I get any thing related to Async Apex Exceution Limits. In Limit Class I saw there are 2 mthods 'getAsyncCalls()' and 'getLimitAsyncCalls()' but both are related reserved for future use.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_limits.htm#apex_System_limits_getAsyncCalls

Kindly help me.

Any help will be greatly appreciated.

Many thanks in advance

Thanks & Regards,
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit. Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then an alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.
Kindly help

Thanks & Regards, 
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit. Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then an alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.
Kindly help
Thanks
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
When I am trying to update an already existing account(update operation) then upon saving future method is called and coordinates are getting stored and in debug logs I can see "ta:coming in after UPDATE"(Kindly refer my trigger code) which is correct.But my worry point is when I am trying to insert a new account and provides map addresses and clicks on Save then also coordinates are getting stored which is also correct but in debug logs I cn still see  "ta:coming in after UPDATE"  instead of 'ta:coming in after insert' because its an insert not an update.

1.Why after trigger is not working and coordinates are getting populated correctly even for new insertion due to after update instead of after insert
2. When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.

Below is trigger which is written on account:
 
trigger geocodeAccountAddress on Account (after insert, after update) {
  
    Set<Id> li=new Set<Id>();
  //bulkify trigger in case of multiple accounts
  //
  if(Trigger.isAfter && Trigger.isInsert){
      System.debug('ta:coming in after insert');
      for(Account acc:Trigger.New){
           System.debug('ta:coming in after insert2');
        if((acc.Location__Latitude__s == null)  && (String.isNotBlank(acc.MapAddressCountry__c))){
  System.debug('ta:coming in after insert1');

li.add(acc.id);
System.debug('ta:coming in after insert4');
												AccountGeocodeAddress.newAccmethod(li);
}  
      }
  }
    
    if(Trigger.isAfter && Trigger.isUpdate){
   System.debug('ta:coming in after UPDATE');
	for(Account acc:Trigger.New){

 if((acc.Location__Latitude__s == null)  &&(String.isNotBlank(acc.MapAddressCountry__c))){
 System.debug('ta:coming in after UPDATE1');

li.add(acc.id);
 System.debug('ta:coming in after Update5');
												AccountGeocodeAddress.newAccmethod(li);
}
}
}
}

My class code is as belows:
 
public class AccountGeocodeAddress {

@future(callout=true)
static public void newAccmethod(set<id> li){

 	
	for(Account a : [SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: li]){

		String address = ' ';

		if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

		address = EncodingUtil.urlEncode(address, 'UTF-8');

		// build callout

		Http h = new Http();

		HttpRequest req = new HttpRequest();

		//req.setEndpoint(‘http://maps.googleapis.com/maps/api/geocode/json?address=’+address+’&sensor=false’);
		req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');

		req.setMethod('GET');

		req.setTimeout(6000);
		try{

			// callout

			HttpResponse res = h.send(req);

			// parse coordinates from response

			JSONParser parser = JSON.createParser(res.getBody());
			system.debug('Harjeet:'+ res.getBody());
			double lat = null;

			double lon = null;

			while (parser.nextToken() != null) {

				if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
								(parser.getText() == 'location')){

					parser.nextToken(); // object start

					while (parser.nextToken() != JSONToken.END_OBJECT){

						String txt = parser.getText();

						parser.nextToken();

						if (txt == 'lat')

						lat = parser.getDoubleValue();

						else if (txt == 'lng')

						lon = parser.getDoubleValue();

					}

				}

			}

			// update coordinates if we get back

			if (lat != null){

				system.debug(lat+' '+lon);

				a.Location__Latitude__s = lat;
				system.debug(a.Location__Latitude__s+'Location__Latitude__s');

				a.Location__Longitude__s= lon;
				system.debug(a.Location__Longitude__s+'Location__Longitude__s');
				update a;

			}

		}

		catch (Exception e) {

			system.debug(e);

		}

	}	

}

}
User-added image


Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet
 
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
When I am trying to update an already existing account(update operation) then upon saving future method is called and coordinates are getting stored and in debug logs I can see "ta:coming in after UPDATE"(Kindly refer my trigger code) which is correct.But my worry point is when I am trying to insert a new account and provides map addresses and clicks on Save then also coordinates are getting stored which is also correct but in debug logs I cn still see  "ta:coming in after UPDATE"  instead of 'ta:coming in after insert' because its an insert not an update.

1.Why after trigger is not working and coordinates are getting populated correctly even for new insertion due to after update instead of after insert
2. When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.

Below is trigger which is written on account:
trigger geocodeAccountAddress on Account (after insert, after update) {
  
    Set<Id> li=new Set<Id>();
  //bulkify trigger in case of multiple accounts
  //
  if(Trigger.isAfter && Trigger.isInsert){
      System.debug('ta:coming in after insert');
      for(Account acc:Trigger.New){
           System.debug('ta:coming in after insert2');
        			 if((acc.Location__Latitude__s == null)  && (String.isNotBlank(acc.MapAddressCountry__c))){
                         System.debug('ta:coming in after insert1');

											li.add(acc.id);
									 System.debug('ta:coming in after insert4');
												AccountGeocodeAddress.newAccmethod(li);
}  
      }
  }
    
    if(Trigger.isAfter && Trigger.isUpdate){
   System.debug('ta:coming in after UPDATE');
					for(Account acc:Trigger.New){

						 if((acc.Location__Latitude__s == null)  && (String.isNotBlank(acc.MapAddressCountry__c))){
                             System.debug('ta:coming in after UPDATE1');

											li.add(acc.id);
												 System.debug('ta:coming in after Update5');
												AccountGeocodeAddress.newAccmethod(li);
}
}
}
}

My class code is as belows:
 
public class AccountGeocodeAddress {

@future(callout=true)
static public void newAccmethod(set<id> li){

 	String  geocodingKey ='AIzaSyD6DLnewg4y0Casi0-iFFjoenLJmmayt8c';
	for(Account a : [SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: li]){

		String address = ' ';

		if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

		address = EncodingUtil.urlEncode(address, 'UTF-8');

		// build callout

		Http h = new Http();

		HttpRequest req = new HttpRequest();

		//req.setEndpoint(‘http://maps.googleapis.com/maps/api/geocode/json?address=’+address+’&sensor=false’);
		req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');

		req.setMethod('GET');

		req.setTimeout(6000);
		try{

			// callout

			HttpResponse res = h.send(req);

			// parse coordinates from response

			JSONParser parser = JSON.createParser(res.getBody());
			system.debug('Harjeet:'+ res.getBody());
			double lat = null;

			double lon = null;

			while (parser.nextToken() != null) {

				if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
								(parser.getText() == 'location')){

					parser.nextToken(); // object start

					while (parser.nextToken() != JSONToken.END_OBJECT){

						String txt = parser.getText();

						parser.nextToken();

						if (txt == 'lat')

						lat = parser.getDoubleValue();

						else if (txt == 'lng')

						lon = parser.getDoubleValue();

					}

				}

			}

			// update coordinates if we get back

			if (lat != null){

				system.debug(lat+' '+lon);

				a.Location__Latitude__s = lat;
				system.debug(a.Location__Latitude__s+'Location__Latitude__s');

				a.Location__Longitude__s= lon;
				system.debug(a.Location__Longitude__s+'Location__Longitude__s');
				update a;

			}

		}

		catch (Exception e) {

			system.debug(e);

		}

	}	

}

}
User-added image
Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet


 
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.


Kindly help me. Below is trigger which is already existing on account:
 
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    //recursive variables
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
	
	//trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
	
	
	//constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
	
	 public void HandleAfterInsert(){ 
        system.debug(LoggingLevel.DEBUG, '***Inside after insert- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isInsert) {
                        Account newAccount = (Account)Trigger.newMap.get(account.Id);

                            if((account.MapAddressStreet__c != newAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != newAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= newAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= newAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= newAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +newAccount.Name);
                                }
                    }

              if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))){
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            } 
        }  

	public void HandleAfterUpdate(){
          system.debug(LoggingLevel.DEBUG, '***Inside after update- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isUpdate) {
                        Account oldAccount = (Account)Trigger.oldMap.get(account.Id);

                            if((account.MapAddressStreet__c != oldAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != oldAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= oldAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= oldAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= oldAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +oldAccount.Name);
                                }
                    }
                     if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))) {
      
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            }  
    }	
	public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }

    // wrapper method to prevent calling futuremethods from an existing future context
    public static void DoAddressGeocode(id accountId) {
       
        if(geocodingCalled || System.isFuture()) {
            System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
                    return;
        }
                
        // if not being called from future context, geocode the address
                        geocodingCalled= true;
                        getLocation(accountId);
    }
	
    @future (callout=true)  // future method needed to run callouts from Triggers
        static public void getLocation( id accountId){
         
        String  geocodingKey ='AIzaSyD6DLnewg4y0Casi0-iFFjoenLJmmayt8c';
        Account a = new Account();
        if(!Test.isRunningTest())
        
        // gather account info
   
        a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');
            req.setMethod('GET');
            req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            
            JSONParser parser = JSON.createParser(res.getBody());
            system.debug('Harjeet:'+ res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }
	
}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.

Kindly help me why few thousand records inserted/updated succesfully using data loader with long/lat and coordinate values and other few thousand records are only inserting/updating but not lat/ong and coordinates are updating.

Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.


Kindly help me. Below is trigger which is already existing on account:
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    //recursive variables
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
	
	//trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
	
	
	//constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
	
	 public void HandleAfterInsert(){ 
        system.debug(LoggingLevel.DEBUG, '***Inside after insert- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isInsert) {
                        Account newAccount = (Account)Trigger.newMap.get(account.Id);

                            if((account.MapAddressStreet__c != newAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != newAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= newAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= newAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= newAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +newAccount.Name);
                                }
                    }

              if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))){
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            } 
        }  

	public void HandleAfterUpdate(){
          system.debug(LoggingLevel.DEBUG, '***Inside after update- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isUpdate) {
                        Account oldAccount = (Account)Trigger.oldMap.get(account.Id);

                            if((account.MapAddressStreet__c != oldAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != oldAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= oldAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= oldAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= oldAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +oldAccount.Name);
                                }
                    }
                     if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))) {
      
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            }  
    }	
	public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }

    // wrapper method to prevent calling futuremethods from an existing future context
    public static void DoAddressGeocode(id accountId) {
       
        if(geocodingCalled || System.isFuture()) {
            System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
                    return;
        }
                
        // if not being called from future context, geocode the address
                        geocodingCalled= true;
                        getLocation(accountId);
    }
	
    @future (callout=true)  // future method needed to run callouts from Triggers
        static public void getLocation( id accountId){
         
        String  geocodingKey ='AIzaSyD6DLnewg4y0Casi0-iFFjoenLJmmayt8c';
        Account a = new Account();
        if(!Test.isRunningTest())
        
        // gather account info
   
        a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');
            req.setMethod('GET');
            req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            
            JSONParser parser = JSON.createParser(res.getBody());
            system.debug('Harjeet:'+ res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }
	
}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.

Kindly help me why few thousand records inserted/updated succesfully using data loader with long/lat and coordinate values and other few thousand records are only inserting/updating but not lat/ong and coordinates are updating.

Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
If I write separate class and trigger to achieve above mentioned functionality then I have no issue everything works smoothly but when I am trying to include my code in already existing account trigger handler then I am not able to make my code bulkify. I am calling my class method on after insert and after update and coordinates fields are updating perfectly but only for single account because I am not able to make my code bulkify and runs for multiple accounts.

Kindly help me. Below is trigger which is already existing on account:
 
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
    
    //trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
    
    //constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
    

 
    
    public void HandleAfterInsert(){ 
        
		//if(!System.isFuture())	           
		//getLocation(newAccs[0].Id);
		DoAddressGeocode(newAccs[0].id);
            
            
        }    
    }
        
    public void HandleAfterUpdate(){
        
                //if(!System.isFuture())     
                    //getLocation(newAccs[0].Id);
                    DoAddressGeocode(newAccs[0].id);
                    
               
            }
               
            
        }    
    }

    public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }
    
    
    
    // wrapper method to prevent calling futuremethods from an existing future context
public static void DoAddressGeocode(id accountId) {
 				 if(geocodingCalled || System.isFuture()) {
                    System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
   						 return;
  					}
                
  		// if not being called from future context, geocode the address
  						geocodingCalled= true;
  						getLocation(accountId);
	}
    @future (callout=true)  // future method needed to run callouts from Triggers
      static public void getLocation( id accountId){
        
        // gather account info
      Account a =[SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      //List<Account> a= new List<Account>();
      //a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false');
        req.setMethod('GET');
        req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            JSONParser parser = JSON.createParser(res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }

}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.
Right now I am not able to do bulkification of my code and wrote only for 1 accounts like DoAddressGeocode(newAccs[0].id)

Any help would be greatly appreciated.

Thanks in advance!

Kindly help
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
If I write separate class and trigger to achieve above mentioned functionality then I have no issue everything works smoothly but when I am trying to include my code in already existing account trigger handler then I am not able to make my code bulkify. I am calling my class method on after insert and after update and coordinates fields are updating perfectly but only for single account because I am not able to make my code bulkify and runs for multiple accounts.

Kindly help me. Below is trigger which is already existing on account:
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
    
    //trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
    
    //constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
    

 
    
    public void HandleAfterInsert(){ 
        
		//if(!System.isFuture())	           
		//getLocation(newAccs[0].Id);
		DoAddressGeocode(newAccs[0].id);
            
            
        }    
    }
        
    public void HandleAfterUpdate(){
        
                //if(!System.isFuture())     
                    //getLocation(newAccs[0].Id);
                    DoAddressGeocode(newAccs[0].id);
                    
               
            }
               
            
        }    
    }

    public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }
    
    
    
    // wrapper method to prevent calling futuremethods from an existing future context
public static void DoAddressGeocode(id accountId) {
 				 if(geocodingCalled || System.isFuture()) {
                    System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
   						 return;
  					}
                
  		// if not being called from future context, geocode the address
  						geocodingCalled= true;
  						getLocation(accountId);
	}
    @future (callout=true)  // future method needed to run callouts from Triggers
      static public void getLocation( id accountId){
        
        // gather account info
      Account a =[SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      //List<Account> a= new List<Account>();
      //a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false');
        req.setMethod('GET');
        req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            JSONParser parser = JSON.createParser(res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }

}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.
Right now I am not able to do bulkification of my code and wrote only for 1 accounts like DoAddressGeocode(newAccs[0].id)

Any help would be greatly appreciated.

Thanks in advance!

Kindly help

 
Dear All,

I am working on a requiremnts which states something as belows:
Craete a new field on Account object which will calculate and store hash value based on a multiple picklist field field "Products" (Products__c)on account object.

Products(Products__c) field have below mentioned values:
  • Baha
  • Vistafix
  • Codacs
  • Hybrid
  • Nucleus
  • CI
  • Acoustic
Solution Approached by me:
I have craeted 1 numer field on Aaccount Object as ProductsHash__c and created 1 trigger as below:
trigger CalculateHash on Account (before insert,before update) { 

public void beforeInsert(Account newAcct){ 

AccountPopulator.populateProductsHash(null, newAcct); 
}
 public void beforeUpdate(Account oldAcc, Account newAcc){ 

AccountPopulator.populateProductsHash(oldAcc, newAcc);
 }
 }
Below is my class:
public class AccountPopulator{ 
public static void populateProductsHash(Account oldAcct, Account newAcct){

 if(oldAcct == null || oldAcct.Products__c != oldAcct.Products__c){ newAcct.ProductsHash__c=System.hashCode(Account.Products__c)‌​; 
}
 
}
 }

Problem Encouter:
Nothing is happening. The newly created field Products_Hash__c on account object is calculating nothing and storing nothing based on the Paroducts__c field on Account​.
Kindly help me what I am doing wrong or what I am missing.

Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet

 
My requirement is to create a new field on Account object which will calculate hash value based on a multiple picklist field "Products" on account object and store in the newly created field in Account object.
I have one field called "Products" in account object which is a multi select picklist field with value: Baha,Vistafix,Codacs,Hybrid,Nucleus,CI ,Acoustic
Kindly help me how to achieve the same. I have no idea about hash and dont know how to proceed.
Any help would be greatly appreciated!
Thanks
My requirement is to create a new field on Account object which will calculate hash value based on a multiple picklist field "Products" on account object and store
I have one field called "Products" in account object which is a multi select picklist field with value: Baha,Vistafix,Codacs,Hybrid,Nucleus,CI ,Acoustic
Kindly help me how to achieve the same. I have no idea about hash and dont know how to proceed.
Any help would be greatly appreciated!
Thanks
My requirement is to create a new field on Account object which will calculate hash value based on a multiple picklist field "Products" on account object and store in the newly created field in Account object.
I have one field called "Products" in account object which is a multi select picklist field with value: Baha,Vistafix,Codacs,Hybrid,Nucleus,CI ,Acoustic
Kindly help me how to achieve the same. I have no idea about hash and dont know how to proceed.
Any help would be greatly appreciated!

Thanks
My requirement is to create a new field on Account object which will calculate hash value based on a multiple picklist field "Products" on account object and store in the new field which is created.
I have one field called "Products" in account object which is a multi select picklist field with value: Baha,Vistafix,Codacs,Hybrid,Nucleus,CI ,Acoustic
Kindly help me how to achieve the same. I have no idea about hash and dont know how to proceed.
Any help would be greatly appreciated!
Thanks
I am developing a functionality where I need to copy emails(emails+attachments) from a child case to parent case on merging.
Right now what ever I have developed I achieved copying emails from child to master case. But when an email is sent with attachments from child case then only email is getting copied to master case not the attachments.
Below is my trigger code
trigger CaseTrigger on Case (before insert, after insert, before update,after update, before delete,after delete) {

    CaseTriggerHandler csHandler = new CaseTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate,trigger.isInsert);

    if (trigger.isAfter && trigger.isInsert) {

       csHandler.HandleAfterInsert();

    }
    if (trigger.isAfter && trigger.isUpdate) {

       csHandler.HandleAfterUpdate();

    }

}

And Below is my trigger handler class(I have kept only useful method related to my question,rest I have omitted for better view and usefulness to my question)
public class CaseTriggerHandler { 

    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }

    List<Case> listOfCase;
    List<Case> newCase;
    List<Case> oldCase;
    Map<Id,Case> newCaseMap;
    Map<Id,Case> oldCaseMap;
    boolean isUpdate;
    boolean isDelete;    

    public CaseTriggerHandler (List<Case> newCase, List<Case> oldCase, 
                               Map<Id,Case> newCaseMap, Map<Id,Case> oldCaseMap, boolean isUpdate, boolean isDelete){
                                   this.newCase = newCase;
                                   this.oldCase = oldCase;
                                   this.newCaseMap = newCaseMap;
                                   this.oldCaseMap = oldCaseMap;
                                   this.isUpdate = isUpdate;
                                   this.isDelete = isDelete;
                               }

    public void HandleAfterUpdate(){       
        if(run){     

            handleemailattachment();

        }
    }

    public void HandleAfterInsert(){

        handleemailattachment();

    } 

    public void handleemailattachment(){
     Map<Id, Id> parentCaseIdMap = new Map<Id, Id>();
     for(Case c : newCase){
         if(c.ParentId!=null)parentCaseIdMap.put(c.Id, c.ParentId);
     }
     // Fetch all the attachments related to the child case
     List<EmailMessage> EmailMessageList= new List<EmailMessage>();
     List<EmailMessage> attachmentToBeCloned = new List<EmailMessage>();
     EmailMessageList = [Select Id,Subject,ParentId,textBody From EmailMessage Where ParentId in:parentCaseIdMap.keySet()];
     for(EmailMessage att : EmailMessageList){
         EmailMessage a = att.clone();
         if(parentCaseIdMap.containsKey(att.ParentId)){
            a.ParentId = parentCaseIdMap.get(att.ParentId);
            attachmentToBeCloned.add(a); 
         } 
    }
    if(attachmentToBeCloned!=null && attachmentToBeCloned.size()>0){
        insert attachmentToBeCloned;
    } 
}
}

Illustration of my requirements:
Suppose I created one Email- to-Case which triggers a creation of cases in SF with 2 emails. Now I linked this case to other Case. Upon merging both of the cases emails are getting copied to master/parent case but if I attach any attachment while creating Email to Case then upon merging only emails are getting copied not attachments .

Kindly help.

Many thanks in advance

Thanks & Regards,
Harjeet
I am currently working on a requirement where I need to notify account owner if some other person (Non Account Owner) Logs a Call against their account . Notification could be in form of a chatter message or email should be sent out to the account owner.

Kindly help to acheive above mentioned requirements.

Many thanks in advance

Thanks & Regards,
Harjeet
Dear All,

I have developed a class which is calling standard REST API to determine Daily Apex Exceution Limits. I am getting error when I am running test class for the same.

Below is my Apex Class:
public class CurrentStorage{


public static void getStorage() {

//fetch session od of user
String sid = Userinfo.getSessionId();

//fetch Instance URL
String baseURL = System.URL.getSalesforceBaseUrl().toExternalForm();
    
    
//Building call out to Standard Salesforce Rest API
HttpRequest req = new HttpRequest();

req.setMethod('GET');
req.setEndpoint(baseURL+'/services/data/v41.0/limits');
req.setHeader('Authorization', 'OAuth '+ sid);

Http http = new Http();
    
HTTPResponse res = http.send(req);

Map<String, Object> m = (Map<String,Object>)JSON.deserializeUntyped(res.getBody());
Map<String, Object> dataStorage = (Map<String,Object>)m.get('DailyAsyncApexExecutions');
System.debug('Map: '+ dataStorage);
System.debug('Current Storage: ' + dataStorage.get('Remaining'));

If(Integer.valueof(dataStorage.get('Max'))*(0.8)<= (Integer.valueof(dataStorage.get('Max')) - Integer.valueof(dataStorage.get('Remaining')))){
    
    Messaging.SingleEmailMessage message = new Messaging.SingleEmailMessage();
                message.toAddresses = new String[] { 'abc@gmail.com','def@gmail.com'};
                //message.optOutPolicy = 'FILTER';
                message.subject = 'Async Apex Limits Threshold Warning';
                message.plainTextBody = 'Your Org Limit of Daily Async Apex Execution reached 80% threshold for '+ baseURL;
                Messaging.SingleEmailMessage[] messages = new List<Messaging.SingleEmailMessage> {message};
                Messaging.SendEmailResult[] results = Messaging.sendEmail(messages);

			if (results[0].success) 
			{
   				 System.debug('The email was sent successfully.');
			} else 
			{
    				System.debug('The email failed to send: ' + results[0].errors[0].message);
			}
         }
    
 
        
            // Send Mail to people
}

}

Below is my test class:
 
@isTest
public class TestCurrentStorage {
    
    static testMethod void validateLocationCallouts() {
    
         RestRequest req = new RestRequest(); 
        req.params.put('DailyAsyncApexExecutions', '250000');
        //req.params.put('Max', '250000');
        req.params.put('Remaining', '200000');
        
        Test.startTest();
   
    
           Test.setMock(HttpCalloutMock.class, new MockHttpResponse());

           CurrentStorage.getStorage();
          Test.stopTest();
    }
    


}

Below is my mock class:
 
@isTest
global class mockHttpResponse implements HttpCalloutMock{
    
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        System.assertEquals('GET', req.getMethod());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
        
        res.setBody('{"Max": "250000","Remaining": "200000"}');
        res.setStatusCode(200);
        res.setStatus('OK');
        return res;
    }

}

When I am trying to run tess class I am getting below error trace logs:
 
Errors:
System.NullPointerException: Attempt to de-reference a null object


Stack Trace:
Class.CurrentStorage.getStorage:
Class.TestCurrentStorage.validateLocationCallouts:

Kindly help me to pass the test class.

Many thanks in advance

Thanks & Regards,
Harjeet​ ​​
Dear All,

I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit(24hrs API Limit). Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then any alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.

I have done few research on the same but didn't get anything concrete. I saw blogs/documentation stating about Limit class and Limit methods but those are having limit method for future but no where I get any thing related to Async Apex Exceution Limits. In Limit Class I saw there are 2 mthods 'getAsyncCalls()' and 'getLimitAsyncCalls()' but both are related reserved for future use.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_limits.htm#apex_System_limits_getAsyncCalls
Kindly help me.

Any help will be greatly appreciated.

Many thanks in advance

Thanks & Regards,
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit(24hrs API Limit). Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then any alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.

I have done few research on the same but didn't get anything concrete. I saw blogs/documentation stating about Limit class and Limit methods but those are having limit method for future but no where I get any thing related to Async Apex Exceution Limits. In Limit Class I saw there are 2 mthods 'getAsyncCalls()' and 'getLimitAsyncCalls()' but both are related reserved for future use.
https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_methods_system_limits.htm#apex_System_limits_getAsyncCalls

Kindly help me.

Any help will be greatly appreciated.

Many thanks in advance

Thanks & Regards,
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit. Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then an alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.
Kindly help

Thanks & Regards, 
Harjeet
I want to send an alert notification when overall organisation Async Apex Execution limit reached 70%of total limit. Say if limit is 2500 and if system already exhausted 1750 of daily Async Apex Limit out of 2500 then an alert should be send to few persons notifying that your organisation limit of Async Apex Executions have reached 70% threshold.
Kindly help
Thanks
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
When I am trying to update an already existing account(update operation) then upon saving future method is called and coordinates are getting stored and in debug logs I can see "ta:coming in after UPDATE"(Kindly refer my trigger code) which is correct.But my worry point is when I am trying to insert a new account and provides map addresses and clicks on Save then also coordinates are getting stored which is also correct but in debug logs I cn still see  "ta:coming in after UPDATE"  instead of 'ta:coming in after insert' because its an insert not an update.

1.Why after trigger is not working and coordinates are getting populated correctly even for new insertion due to after update instead of after insert
2. When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.

Below is trigger which is written on account:
 
trigger geocodeAccountAddress on Account (after insert, after update) {
  
    Set<Id> li=new Set<Id>();
  //bulkify trigger in case of multiple accounts
  //
  if(Trigger.isAfter && Trigger.isInsert){
      System.debug('ta:coming in after insert');
      for(Account acc:Trigger.New){
           System.debug('ta:coming in after insert2');
        if((acc.Location__Latitude__s == null)  && (String.isNotBlank(acc.MapAddressCountry__c))){
  System.debug('ta:coming in after insert1');

li.add(acc.id);
System.debug('ta:coming in after insert4');
												AccountGeocodeAddress.newAccmethod(li);
}  
      }
  }
    
    if(Trigger.isAfter && Trigger.isUpdate){
   System.debug('ta:coming in after UPDATE');
	for(Account acc:Trigger.New){

 if((acc.Location__Latitude__s == null)  &&(String.isNotBlank(acc.MapAddressCountry__c))){
 System.debug('ta:coming in after UPDATE1');

li.add(acc.id);
 System.debug('ta:coming in after Update5');
												AccountGeocodeAddress.newAccmethod(li);
}
}
}
}

My class code is as belows:
 
public class AccountGeocodeAddress {

@future(callout=true)
static public void newAccmethod(set<id> li){

 	
	for(Account a : [SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: li]){

		String address = ' ';

		if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

		address = EncodingUtil.urlEncode(address, 'UTF-8');

		// build callout

		Http h = new Http();

		HttpRequest req = new HttpRequest();

		//req.setEndpoint(‘http://maps.googleapis.com/maps/api/geocode/json?address=’+address+’&sensor=false’);
		req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');

		req.setMethod('GET');

		req.setTimeout(6000);
		try{

			// callout

			HttpResponse res = h.send(req);

			// parse coordinates from response

			JSONParser parser = JSON.createParser(res.getBody());
			system.debug('Harjeet:'+ res.getBody());
			double lat = null;

			double lon = null;

			while (parser.nextToken() != null) {

				if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
								(parser.getText() == 'location')){

					parser.nextToken(); // object start

					while (parser.nextToken() != JSONToken.END_OBJECT){

						String txt = parser.getText();

						parser.nextToken();

						if (txt == 'lat')

						lat = parser.getDoubleValue();

						else if (txt == 'lng')

						lon = parser.getDoubleValue();

					}

				}

			}

			// update coordinates if we get back

			if (lat != null){

				system.debug(lat+' '+lon);

				a.Location__Latitude__s = lat;
				system.debug(a.Location__Latitude__s+'Location__Latitude__s');

				a.Location__Longitude__s= lon;
				system.debug(a.Location__Longitude__s+'Location__Longitude__s');
				update a;

			}

		}

		catch (Exception e) {

			system.debug(e);

		}

	}	

}

}
User-added image


Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet
 
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided. Map addresses are new fields created on accounts object(map street,map city,map postal code,map countrymap state)

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
When I am trying to insert account records through data loader some accounts have updated coordinates after insertion whereas some doesn't have coordinates inserted.
I tried inserting around 17K records upon which 5K records inserted succesfully and also their corresponding coordinates are updated. Rest 12K records also inserted succesfully but their coordinates are not updated.


Kindly help me. Below is trigger which is already existing on account:
 
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    //recursive variables
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
	
	//trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
	
	
	//constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
	
	 public void HandleAfterInsert(){ 
        system.debug(LoggingLevel.DEBUG, '***Inside after insert- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isInsert) {
                        Account newAccount = (Account)Trigger.newMap.get(account.Id);

                            if((account.MapAddressStreet__c != newAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != newAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= newAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= newAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= newAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +newAccount.Name);
                                }
                    }

              if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))){
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            } 
        }  

	public void HandleAfterUpdate(){
          system.debug(LoggingLevel.DEBUG, '***Inside after update- ' );
        
            for(Account account : newAccs) {
  
                //check if Map Address has been updated
                Boolean addressChangedFlag = false;

                    if(Trigger.isUpdate) {
                        Account oldAccount = (Account)Trigger.oldMap.get(account.Id);

                            if((account.MapAddressStreet__c != oldAccount.MapAddressStreet__c) ||
                                (account.MapAddressCity__c != oldAccount.MapAddressCity__c) ||
                                (account.MapPostalState__c!= oldAccount.MapPostalState__c) ||
                                (account.MapAddressPostalCode__c!= oldAccount.MapAddressPostalCode__c) || 
                                (account.MapAddressCountry__c!= oldAccount.MapAddressCountry__c)) {
         
                                    addressChangedFlag = true;
         
                                    System.debug(LoggingLevel.DEBUG, '***Address changed for - ' +oldAccount.Name);
                                }
                    }
                     if(((account.Location__Latitude__s == null) || (addressChangedFlag == true)) && (String.isNotBlank(account.MapAddressCountry__c))) {
      
                    System.debug(LoggingLevel.DEBUG,'***Geocoding Account - ' + account.Name);
                    AccountTriggerHandler.DoAddressGeocode(account.id);
                }   
            }  
    }	
	public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }

    // wrapper method to prevent calling futuremethods from an existing future context
    public static void DoAddressGeocode(id accountId) {
       
        if(geocodingCalled || System.isFuture()) {
            System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
                    return;
        }
                
        // if not being called from future context, geocode the address
                        geocodingCalled= true;
                        getLocation(accountId);
    }
	
    @future (callout=true)  // future method needed to run callouts from Triggers
        static public void getLocation( id accountId){
         
        String  geocodingKey ='AIzaSyD6DLnewg4y0Casi0-iFFjoenLJmmayt8c';
        Account a = new Account();
        if(!Test.isRunningTest())
        
        // gather account info
   
        a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
            Http h = new Http();
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://maps.googleapis.com/maps/api/geocode/json?address='+address + '&key='+ geocodingKey+ '&sensor=false');
            req.setMethod('GET');
            req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            
            JSONParser parser = JSON.createParser(res.getBody());
            system.debug('Harjeet:'+ res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }
	
}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.

Kindly help me why few thousand records inserted/updated succesfully using data loader with long/lat and coordinate values and other few thousand records are only inserting/updating but not lat/ong and coordinates are updating.

Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet
Dear All,

I am immense need of help from all of you. After giving a much thought and so much brainstorming happened finally I turned up here for advise.

Requirement:
I need to fetch coordinates value of account based on Map address provided

Solution approach
I create few fields on accounts like MapAddressCity,MapAddressState,MapAddressStreet,MapAddressPostalCode and MapAddresscountry on account. When an user enters values in Map fields and clicks on save button I am calling Google API. Google API will returns one coordinate value based on address filled in Map fields. I have created one field called "Location"(Data Type-Geolocation) which will stores coordinates and also I created 2 formula fields which stores the longitude and latitude values of coordinates in "LonField" and "LatField" respectively

If an user enters below in account:
MapAddressCity: San Francisco  
MapAddressCountry: United States  
MapAddressPostalCode: 94105  
MapPostalState: CA  
MapAddressStreet: One Market Street
and clicks on Save-Google API call will be made and below information wiull be stored on account:
Location-37°47'38''N 122°23'41''W  
LongValue-122.3948  
LatValue37.7939

My Question:
In our org there is already one trigger written on account and there is already one accounthandler class and we always follow best practices so I didnt write a separate trigger and class to achieve above mentioned requirement. I am reusing same accounttriggerhandler class and apex trigger which is written on account.
If I write separate class and trigger to achieve above mentioned functionality then I have no issue everything works smoothly but when I am trying to include my code in already existing account trigger handler then I am not able to make my code bulkify. I am calling my class method on after insert and after update and coordinates fields are updating perfectly but only for single account because I am not able to make my code bulkify and runs for multiple accounts.

Kindly help me. Below is trigger which is already existing on account:
//Single Master Trigger on Account using Handlers for each individual actions
trigger AccountTrigger on Account (before delete, before insert, before update, after insert, after update,after delete) {

    checkRecursive.isRunOnce = true; // ToDo : Need to change the recursive handling logic
    AccountTriggerHandler accHandler = new AccountTriggerHandler(trigger.new,trigger.old,trigger.newMap,trigger.oldMap,trigger.isUpdate);
    
 
    if(trigger.isBefore && trigger.isInsert){
        accHandler.HandleBeforeInsert();
        
    }
    if(trigger.isBefore && trigger.isUpdate){
        accHandler.HandleBeforeUpdate();
       
    }
    if(trigger.isAfter && trigger.isInsert) {  
        accHandler.HandleAfterInsert();
    
    }
  
    if(trigger.isAfter && trigger.isUpdate){
        accHandler.HandleAfterUpdate();
    
    }
 
    if(trigger.isBefore && trigger.isDelete)
        accHandler.HandleBeforeDelete();

    if(trigger.isAfter && trigger.isDelete)
        accHandler.HandleAfterDelete();       
}

My class code is as belows:
 
//Handler Class to handle Account Trigger
public class AccountTriggerHandler {
    
    public static Boolean runAccountTriggerHandler = true;
    private static Boolean geocodingCalled = false;

    
    public static boolean run = true;
    public static boolean runOnce(){
        if(run){
            run=false;
            return true;
        }else{
            return run;
        }
    }
    
    //trigger variables
    List<Account> newAccs;
    List<Account> oldAccs;
    Map<Id,Account> newAccMap;
    Map<Id,Account> oldAccMap;
    Id accountId;
    boolean isUpdate;
    
    //constructor
    public AccountTriggerHandler(List<Account> newAccs, List<Account> oldAccs, 
                                 Map<Id,Account> newAccMap, Map<Id,Account> oldAccMap, boolean isUpdate){
        this.newAccs = newAccs;
        this.oldAccs = oldAccs;
        this.newAccMap = newAccMap;
        this.oldAccMap = oldAccMap;
        this.isUpdate = isUpdate;
        this.accountId= accountId;                          
        this.consentService = new ConsentManagementService(Account.sObjectType);
    }
    

 
    
    public void HandleAfterInsert(){ 
        
		//if(!System.isFuture())	           
		//getLocation(newAccs[0].Id);
		DoAddressGeocode(newAccs[0].id);
            
            
        }    
    }
        
    public void HandleAfterUpdate(){
        
                //if(!System.isFuture())     
                    //getLocation(newAccs[0].Id);
                    DoAddressGeocode(newAccs[0].id);
                    
               
            }
               
            
        }    
    }

    public void HandleBeforeDelete(){
        
    }
 
    public void HandleAfterDelete(){
        
    }
    
    
    
    // wrapper method to prevent calling futuremethods from an existing future context
public static void DoAddressGeocode(id accountId) {
 				 if(geocodingCalled || System.isFuture()) {
                    System.debug(LoggingLevel.WARN,'***Address Geocoding Future Method Already Called - Aborting...');
   						 return;
  					}
                
  		// if not being called from future context, geocode the address
  						geocodingCalled= true;
  						getLocation(accountId);
	}
    @future (callout=true)  // future method needed to run callouts from Triggers
      static public void getLocation( id accountId){
        
        // gather account info
      Account a =[SELECT MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      //List<Account> a= new List<Account>();
      //a= [SELECT id, MapAddressCity__c,MapAddressCountry__c,MapAddressPostalCode__c,MapAddressStreet__c,MapPostalState__c FROM Account  WHERE id =: accountId];
      
        // create an address string
        String address = '';
        if (a.MapAddressStreet__c!= null)
            address += a.MapAddressStreet__c+', ';
        if (a.MapAddressCity__c != null)
            address += a.MapAddressCity__c +', ';
        if (a.MapPostalState__c!= null)
            address += a.MapPostalState__c+' ';
        if (a.MapAddressPostalCode__c!= null)
            address += a.MapAddressPostalCode__c+', ';
        if (a.MapAddressCountry__c!= null)
            address += a.MapAddressCountry__c;

        address = EncodingUtil.urlEncode(address, 'UTF-8');

        // build callout
        Http h = new Http();
        HttpRequest req = new HttpRequest();
        req.setEndpoint('http://maps.googleapis.com/maps/api/geocode/json?address='+address+'&sensor=false');
        req.setMethod('GET');
        req.setTimeout(60000);

        try{
            // callout
            HttpResponse res = h.send(req);

            // parse coordinates from response
            JSONParser parser = JSON.createParser(res.getBody());
            double lat = null;
            double lon = null;
            while (parser.nextToken() != null) {
                if ((parser.getCurrentToken() == JSONToken.FIELD_NAME) &&
                    (parser.getText() == 'location')){
                       parser.nextToken(); // object start
                       while (parser.nextToken() != JSONToken.END_OBJECT){
                           String txt = parser.getText();
                           parser.nextToken();
                           if (txt == 'lat')
                               lat = parser.getDoubleValue();
                           else if (txt == 'lng')
                               lon = parser.getDoubleValue();
                       }

                }
            }

            // update coordinates if we get back
            if (lat != null){
                a.Location__Latitude__s = lat;
                a.Location__Longitude__s = lon;
                update a;
            }

        } catch (Exception e) {
        }
    }

}

I have removed all the extra codes and methods from class and only kept my method in class to have a better visibility for code to all of you.
I am calling "DoAddressGeocode​" method on HandleAfterInsert and HandleAfterUpdate.
Right now I am not able to do bulkification of my code and wrote only for 1 accounts like DoAddressGeocode(newAccs[0].id)

Any help would be greatly appreciated.

Thanks in advance!

Kindly help

 
Dear All,

I am working on a requiremnts which states something as belows:
Craete a new field on Account object which will calculate and store hash value based on a multiple picklist field field "Products" (Products__c)on account object.

Products(Products__c) field have below mentioned values:
  • Baha
  • Vistafix
  • Codacs
  • Hybrid
  • Nucleus
  • CI
  • Acoustic
Solution Approached by me:
I have craeted 1 numer field on Aaccount Object as ProductsHash__c and created 1 trigger as below:
trigger CalculateHash on Account (before insert,before update) { 

public void beforeInsert(Account newAcct){ 

AccountPopulator.populateProductsHash(null, newAcct); 
}
 public void beforeUpdate(Account oldAcc, Account newAcc){ 

AccountPopulator.populateProductsHash(oldAcc, newAcc);
 }
 }
Below is my class:
public class AccountPopulator{ 
public static void populateProductsHash(Account oldAcct, Account newAcct){

 if(oldAcct == null || oldAcct.Products__c != oldAcct.Products__c){ newAcct.ProductsHash__c=System.hashCode(Account.Products__c)‌​; 
}
 
}
 }

Problem Encouter:
Nothing is happening. The newly created field Products_Hash__c on account object is calculating nothing and storing nothing based on the Paroducts__c field on Account​.
Kindly help me what I am doing wrong or what I am missing.

Any help will be greatly appreciated!

Thanks in advance

Thanks & Regards,
Harjeet

 
Hello,

I can see there is a REST API that can be called so we can see where we are currently with all of the Salesforce limits. https://instance.salesforce.com/services/data/v37.0/limits/

We would like to be able to track the limits periodically using a trigger. Inside this trigger we would like to view the Daily Async Apex Executions, and do something if the number left is below a threshold

The only method that I can see of grabbing this number real time is with that REST API. Is there another way to grab that number? e.g. is there an object that I can query using SOQL? Alternatively, am I wrong in thinking it's impossible to grab the results from that REST API in a trigger?

I have searched for all resources on the topic and have come up blank. If someone could shine a light on this it would be greatly appreciated

Thanks
Mark
(https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)
"The maximum number of asynchronous Apex method executions (batch Apex, future methods, Queueable Apex, and scheduled Apex) per a 24-hour period: 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater"

When we're talking about batch Apex, for example, are we just talking about start(), execute(), finish() methods being applied to that limit or are all methods - even custom methods - also included in that figure as well?

Also is there a way to see how close we are getting to that limit every day?  I looked at the Limits class but didn't see any direct methods there.  We have a couple of huge batch classes that run once a week and I want to make sure we're not getting too close to that limit.

We are experiencing issues with our APEX components where we are routinely running into issues with exceeding our API AsyncOperations.  The errorrs we get are the following:

 

caused by: System.AsyncException: Rate Limiting Exception : AsyncApexExecutions Limit exceeded.

 

Are there any tools out there that would allow us to see who and what is making all these Async calls.  I've tried using the Apex Jobs monitoring tool in SFDC but I think the Async jobs that are listed in this tool are the Async jobs that have been successfully submitted to the system AND NOT the total # of requests that have been made. If we were able to see how many total requests are being made, then I think we should be able zero in on the offending class and object.

 

Any suggestions?