You need to sign in to do that
Don't have an account?
KitagawaSan805
Geocoding Trigger help
I am working on a trigger that will populate longitude and latitude fields on the account object. I have a start on it, but I am getting an error:
"Error:Apex trigger AccountBeforeUpsert caused an unexpected exception, contact your administrator: AccountBeforeUpsert: System.LimitException: Too many script statements: 200001"
Class:
public with sharing class GeoUtilities { @future(callout=true) public static void updateAccounts(List<Id> accountIds) { // get the custom city, state and country fields from account List<account> accounts = [select Id, Name, BillingStreet, BillingCity, BillingState, BillingCountry from Account where Id in :accountIds ]; for(Account theAccount: accounts) { List<string> address = new List<string>(); address.add(theAccount.BillingStreet); address.add(theAccount.BillingCity); address.add(theAccount.BillingState); address.add(theAccount.BillingCountry); String[] coordinates = GeoUtilities.getCoordinates(address); if(coordinates != null) { Decimal pos1 = Decimal.valueOf(coordinates[0]); theAccount.Latitude__c = pos1; Decimal pos2 = Decimal.valueOf(coordinates[1]); theAccount.Longitude__c = pos2; system.debug(Logginglevel.ERROR,'GeoUtilities coordinates ' + pos1 + ' ' + pos2 ); } else { system.debug(Logginglevel.ERROR,'GeoUtilities no coordinates!!! for address' ); } } update accounts; } /* Input list of address parts: street, city, state, country. Output: list of coordinates: latitude, longitude */ public static String[] getCoordinates(String[] addressParts) { String[] Coordinates; String address = ''; boolean needComma = false; if(address.length() == 0) { system.debug(Logginglevel.ERROR, 'GeoUtilities getCoordinates no address provided. Return null'); return null; } String url = 'http://maps.google.com/maps/geo?'; url += 'q=' + address; url += '&output=csv'; system.debug(Logginglevel.ERROR,'GeoUtilities getCoordinates url: ' + url); Http h = new Http(); HttpRequest req = new HttpRequest(); req.setHeader('Content-type', 'application/x-www-form-urlencoded'); req.setHeader('Content-length', '0'); req.setEndpoint(url); req.setMethod('POST'); String responseBody; if (!Test.isRunningTest()){ // Methods defined as TestMethod do not support Web service callouts HttpResponse res = h.send(req); responseBody = res.getBody(); } else { // dummy data responseBody = '200,4,48.5,-123.67'; } String[] responseParts = responseBody.split(',',0); // the response has four parts: // status code, quality code, latitude and longitude Coordinates = new String[2]; Coordinates[0] = responseParts[2]; Coordinates[1] = responseParts[3]; return Coordinates; } static testMethod void testGetGeo() { String[] addressParts; String[] coordinates; addressParts = new List<string>(); addressParts.add(''); addressParts.add('San Diego'); addressParts.add('CA'); addressParts.add('USA'); coordinates = GeoUtilities.getCoordinates(addressParts); System.assert(coordinates != null); System.assertEquals(2, coordinates.size()); } }
Trigger:
trigger AccountBeforeUpsert on Account (before insert, before update) { system.debug(Logginglevel.ERROR,'AccountBeforeUpsert geo updates'); List<Id> accountsToUpdate = new List<Id>(); for(Account theAccount: trigger.new) { boolean needsUpdate = false; if(Trigger.isInsert) { needsUpdate = true; } else { Account beforeUpdate = System.Trigger.oldMap.get(theAccount.Id); needsUpdate = ( (beforeUpdate.BillingStreet != theAccount.BillingStreet) || (beforeUpdate.BillingCity != theAccount.BillingCity) || (beforeUpdate.BillingState != theAccount.BillingState) || (beforeUpdate.BillingCountry != theAccount.BillingCountry) ); } if(needsUpdate) { accountsToUpdate.add(theAccount.Id); } } if(accountsToUpdate.size() >0 ) { Integer cnt = 0; Integer i = 0; Integer x = accountsToUpdate.size(); x = (x>100? 100: x); while(i < x){ List<account> smallList = new List<account>(); for(Integer k = 0; k == x;) break; } GeoUtilities.updateAccounts(accountsToUpdate); } }
Any help with this would be greatly appreciated. Credit for much of the code goes to Bryan at https://bryandf11.wordpress.com/2011/08/22/geocoding-in-apex-triggers-callouts-and-future-methods/
Thanks!
Please see my updated geocoder class here. It contains a link to the orignal article in case you want background.
All Answers
Please see my updated geocoder class here. It contains a link to the orignal article in case you want background.
Thanks!!!
The only question I have is on the last part about scheduling it to run 10x per hour. I see the code for it, (below), but where do I put that?
Thanks again for all your help!
The code you quoted must be executed anonymously. You can do this in the eclipse IDE or in the developer console.
Here and here are some links about doing this in the IDE. It should be fairly straight forward in the developer console.
Also, you can check your scheduled jobs under: Your Name->Setup->Admin Setup->Monitoring->Scheduled Jobs.
Once you have initialized the geolocations for your system, you will want to only schedule this once per hour. That way you can save your other scheduled job slots (there is a maximum) for use elsewhere.