• devrequirement
  • NEWBIE
  • 0 Points
  • Member since 2012

  • Chatter
    Feed
  • 0
    Best Answers
  • 0
    Likes Received
  • 0
    Likes Given
  • 9
    Questions
  • 14
    Replies

Hi all,

 

I was wondering if it is possible to read the records from Excel file, then compare the records with existing Task records(in millions) in SFDC via common key, create new records with same data from Excel file except the Last Modified Date (which is what we need to update), then delete the original task record. Is there any links I can refer to do all these things, if possible?
 

Or should we just export the existing records(in millions), delete those records from salesforce, update the last modified date in excel sheet and insert new records with only the last modified date updated?

 

Which one seems to be the more efficient way to do it? Also, could you also please recommend what are the things that should be on my checklist before I delete those Task records?

 

Thanks!! Apolgies for bombardment of questions, but I really need second point of view.

 

 

 

Hello all,

 

I was wondering if there is any way to modify the following query to limit the results to only  records that were updated after the last batch job 'EmailBatch'  was either ran or completed?

 

query = 'select id,email,hasoptedoutofemail,lastmodifieddate from contact order by email asc,lastmodifieddate asc'; 

The query is currently being used in the start method of a batch apex and I have been constantly receiving following error. (Note I scheduled this job couple of days ago at a particular time and the error was displayed. Next day, the batch was processed perfectly. And again the error occurs today.)

 

First error: SQLException [java.sql.SQLException: ORA-01013: user requested cancel of current operation
: select /*ApexBatch.Class.EmailOptOutBatch.start: line 26*/ *
from (select "Id"
from (select upper(t.email) "_SORT_COL_0",
t.last_update "LastModif...

 

Thanks for your time!!

Hi All.

 

In our organization we have a Task object consisting of 8 million records. Our ultimate task is to change the Last Modified Date(After opening up the field from SFDC support) in activities of the millions of records that were initially imported to SFDC from the previous system. Now, I cannot even do a query to get the exact number of records we're trying to export/import because it always times out.

 

The only criteria we have is OldSystem_Action_Id ! = null which separates the records originated in the old system.

 

I was thinking if we could utilize the batch functionality to break down the processes through the Apex Data Loader. If so, are you aware of any step by step procedures on how I can utilize this methodology. Also, will it be possible to extract the millions of records in separate files?

 

Any help is appreciated! Thanks in advance.

All,

I need to develop a webservice, which will be called in a trigger after some field update. This webservice should send the email to my personal email address. Could someone guide me with the steps required to complete this mini-project?

 

Thanks!!!

Following is the test class which garnered 91% test coverage in the sandbox for a class which was doing it's job already. However when I tried to validate the class through change sets while deploying it, the process was throwing me an error of FIELD_CUSTOM_VALIDATION_EXCEPTION at the line insert conobj2;

Stuffs I tried were: Setting up a user with a system admin profile to be associated in the test class as running user, create a particular record type and associate it with the process while confirming running user(which was me)'s profile has option to access the record type of the object, create a campaign then associate it with the contacts and accounts just to mimik the process. However, i was constantly being thrown the error.

Surprisingly when I commented out the conobj2, the validation and deployment was successful. However, could you please provide me some insight on how to correct the code in order to follow what it is supposed to do in the first place.
 Thanks in advance!!!!

@isTest(SeeAllData =true)

    private class EmailOptOutBatchTest{
    
    static testmethod void testEmailOptOutBatch() {
        Account accObj = new Account();
        accObj.Name='EmailOptOutTestUser';
        accObj.Num_of_Users__c=5;
        accObj.Type='Customer';
        accObj.Location_Type__c='Closed';
        accObj.AccountNumber='12345';
        accObj.BillingCountry='Nepal';
        accObj.Active__c = true;
       
        insert accObj;
        
       
        
        Contact ConObj1 = new Contact();
        ConObj1.Active__c = true ;       
        ConObj1.AccountId = AccObj.Id;
        ConObj1.FirstName = 'Paul';
        ConObj1.LastName = 'McCartney';
        ConObj1.Email='PM@p.com';
        ConObj1.Function__c = 'Unknown';
        ConObj1.HasOptedOutOfEmail=False;
        
        insert conObj1;
        
        Contact ConObj2 = new Contact();
      
        ConObj2.Active__c = true;
        ConObj2.AccountId = AccObj.Id;
        ConObj2.FirstName = 'John';
        ConObj2.LastName = 'Lennon';
        ConObj2.Email='PM@p.com';
        ConObj2.Function__c = 'Unknown';
        ConObj2.HasOptedOutOfEmail= True;
        //insert conObj2;
     
        
        if( Test.isRunningTest()) {
        ConObj1.HasOptedOutOfEmail = ConObj2.HasOptedOutOfEmail;
        }
        
        List<Contact> ContactListall = new List<Contact>();
        ContactListall.add(conObj1);
        ContactListall.add(conObj2);
       
 
         Test.startTest();
         
         EmailOptOutBatch objEmailOptOutBatch = new EmailOptOutBatch(true);
         ID batchprocessid = Database.executeBatch(objEmailOptOutBatch);
        
         Test.stopTest();
          }
}

In the following method within a webservice, I am getting an error when trying to insert new lead and the error shows from salesforce webservice as following

 

System.StringException : Invalid Id

 

For the following class, it's the second red higlighted line.

 

Please let me know if anyone has any knowledge on how we might tackle this problem.

 

Thank you!

   public static EWebAPIUtils.APILeadInsert insertLead(String companyName, String partnerName, String street, String city, String state, String zip, String country, String website, String phone, String fax, Integer noOfEmployees, String sicCode, String primarySector, String industry, String primaryVertical, String firstName, String lastName, String title, String email, String primaryProduct, String partnerSiteId, String partnerEmailAddress, Date expectedCloseDate, Decimal budget, String region, Decimal annualRevenue, String campaignId)
    {   
       
        Integer year = math.mod(date.today().year(),100);
        String campName = 'NA_VAR_FY'+year;
        System.debug('campName :'+campName);
        try{
            campaignId =  [Select Id From Campaign where name = :campName].id;
        }catch(Exception e)
        {
            System.debug('Record not found');
        }
        Savepoint sp;
        Id ruleId;
        EWebAPIUtils.APILeadInsert result = new EWebAPIUtils.APILeadInsert();
       
        Lead newLead = new Lead();
        newLead.Company = companyName;
        newLead.Partner_Name__c = partnerName;
        newLead.Street = street;
        newLead.City = city;
        newLead.State = state;
        newLead.PostalCode = zip;
        newLead.Country = country;
        newLead.Website = website;
        newLead.Phone = phone;
        newLead.Fax = fax;
        if(noOfEmployees != null)
        {
            newLead.NumberOfEmployees = noOfEmployees; 
        }
        newLead.Primary_SIC_Code__c = sicCode;
        newLead.Primary_Sector__c = primarySector;  
        newLead.Primary_Industry__c = industry;
        newLead.Primary_Vertical__c = primaryVertical;
        newLead.FirstName= firstName;
        newLead.LastName= lastName;
        newLead.Title = title;
        newLead.Email = email;
        newLead.Solution__c= primaryProduct;
        newLead.Partner_Site_ID__c = partnerSiteId;  
        newLead.Partner_Email_Address__c = partnerEmailAddress;
        newLead.Expected_Close_Date__c = expectedCloseDate;
        if(budget != null)
        {
            newLead.Budget__c = budget;
        }
        newLead.Region__c = region;
        if(annualRevenue != null)
        {
            newLead.AnnualRevenue = annualRevenue;
        }
        newLead.Lead_Type__c =  'Partner';
        
        sp = Database.setSavepoint();
        
        try{
        //get the Id for the Standard Assignment Rule from Organization
            ruleId = [Select Id From AssignmentRule where name = 'Universal Lead Assignment Rule'].id;
        }catch(Exception ex)
        {
            System.debug('Assignment Rule not found');
        }
        //Use DMLOptions to provide exta infomation during a transaction. 
        //Create DMLoptions object
        Database.DMLOptions dmo = new Database.DMLOptions();
        
        //AssignmentRuleHeader specifies the Assignment Rule to be used when the lead is created.
        dmo.AssignmentRuleHeader.assignmentRuleId = ruleId;
        
        //Sets the DMLOptions object for the sObject    
        newLead.setOptions(dmo);
        
        try{
            insert newLead;  

            CampaignMember objCampaignMember = new CampaignMember();
            objCampaignMember.CampaignId = campaignId;
            objCampaignMember.LeadId = newLead.Id;
            insert objCampaignMember;
            
            result.iReturnCode = EWebAPIUtils.STATUS_CREATED;
            result.strMessage = EWebAPIUtils.LEAD_INSERTED_SUCCESSFULLY ;
            EWebAPIUtils.APILeadInsert objAPILeadInsert= result.insertLead(newLead.id,result.iReturnCode,result.strMessage );    
            return objAPILeadInsert;          
            
        }catch(QueryException e)
        {
             //We reached here as there was some exception occured.
            Database.rollback(sp);
           
            result.iReturnCode = EWebAPIUtils.STATUS_ISE;
            result.strMessage = EWebAPIUtils.LEAD_INSERT_FAILED ;
            return result.insertLead(newLead.id,result.iReturnCode,result.strMessage);
        }
    }

Below is the Test Class for the Batch class in the following snippet of the code. The test coverage stops right here : global Database.QueryLocator start(Database.BatchableContext BC){

In need of guidance and help.

 

TEST CLASS

@isTest(SeeAllData =true)

    private class UpdateEmailOptOutFieldBatchableTest{
    
    static testmethod void testUpdateEmailOptOutFieldBatchable() {
        
       
    
        Contact ConObj1 = new Contact();
        ConObj1.FirstName = 'Paul';
        ConObj1.LastName = 'McCartney';
        ConObj1.Email='PM@p.com';
        //ConObj1.Id ='0038000001HeyJuDEE';
        ConObj1.HasOptedOutOfEmail=False;
        //ConObj1.LastModifiedDate = 
        insert conObj1;
        
        Contact ConObj2 = new Contact();
        ConObj2.FirstName = 'John';
        ConObj2.LastName = 'Lennon';
        ConObj2.Email='PM@p.com';
        //ConObj2.Id ='0038000002ImaGiNEE';
        ConObj2.HasOptedOutOfEmail=False;
        //ConObj2.LastModifiedDate = 
        insert conObj2;
            
        Contact ConObj3 = new Contact();
        ConObj3.FirstName = 'Ringo';
        ConObj3.LastName = 'Star';
        ConObj3.Email='RS@p.com';
        //ConObj3.Id ='0038000003LsdSkYEE';
        ConObj3.HasOptedOutOfEmail=False;
        //ConObj3.LastModifiedDate = 
        insert conObj3;
        
        Contact ConObj4 = new Contact();
        ConObj4.FirstName = 'George';
        ConObj4.LastName = 'Harrison';
        ConObj4.Email='RS@p.com';
        //ConObj4.Id ='0038000004GenTlYEE';
        ConObj4.HasOptedOutOfEmail=True;
        //ConObj4.LastModifiedDate = 
        insert conObj4;

        Contact ConObj5 = new Contact();
        ConObj5.FirstName = 'Led';
        ConObj5.LastName = 'Zeppelin';
        ConObj5.Email='LZ@p.com';
        //ConObj5.Id ='0038000004HeaVeNNN';
        ConObj5.HasOptedOutOfEmail=False;
        //ConObj5.LastModifiedDate = 
        insert conObj5;

        Contact ConObj6 = new Contact();
        ConObj6.FirstName = 'Jimi';
        ConObj6.LastName = 'Hendrix';
        ConObj6.Email='LZ@p.com';
        //ConObj6.Id ='0038000004CasTlEEE';
        ConObj6.HasOptedOutOfEmail=True;
        //ConObj6.LastModifiedDate = 
        insert conObj6;
        
        List<Contact> ContactListall = new List<Contact>();
        ContactListall.add(conObj1);
        ContactListall.add(conObj2);
        ContactListall.add(conObj3);
        ContactListall.add(conObj4);
        ContactListall.add(conObj5);
        ContactListall.add(conObj6);
 
         Test.startTest();
         //String query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT'; 
         //UpdateEmailOptOutFieldBatchable objUpdateEmailOptOutFieldBatchable = new UpdateEmailOptOutFieldBatchable(query);
         UpdateEmailOptOutFieldBatchable objUpdateEmailOptOutFieldBatchable = new UpdateEmailOptOutFieldBatchable();
         ID batchprocessid = Database.executeBatch(objUpdateEmailOptOutFieldBatchable);
         System.abortJob(batchprocessid);
         Test.stopTest(); 
          }
}

 

BATCH CLASS

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<sObject>{
// declaring the variable
global final String query;
 
/* Constructor method to fetch contacts from the database*/
 
global UpdateEmailOptOutFieldBatchable(){
    query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT ORDER BY LastModifiedDate DESC';
}
 
/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
    return Database.getQueryLocator(query);
}
 
global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
                List <Contact> ContactsToUpdate = new List<Contact>();
                Set <String> ContactIDsToUpdate = new Set<String>();
                for(integer i=0; i<allContactList.size()-1; i++)
                {
                                for(integer j=i+1; j<allContactList.size()-1; j++)
                                {
                                                If (allContactList[i].email == allContactList[j].email && ContactIDsToUpdate.contains(allContactList[j].Id)==False)
                                                {
                                                                ContactIDsToUpdate.add(allContactList[j].Id);
                                                                allContactList[j].HasOptedOutOfEmail=allContactList[i].HasOptedOutOfEmail;
                                                                ContactsToUpdate.add(allContactList[j]);
                                                }
                                }
                }             
                If (ContactsToUpdate.isempty()==False)
                {
                                update ContactsToUpdate;
                }
}
global void finish(Database.BatchableContext BC){
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setToAddresses(new String[]{'rkshrest@gmail.com'});
    mail.setReplyTo('rkshrest@gmail.com');
    mail.setSenderDisplayName('Batch Processing');
    mail.setSubject('Batch Process Completed');
    mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }
}

Hi All,

 

Following are the two approaches to find the contacts with same email value as the contact record that was latest updated and provide the duplicate contacts the same Email Opt Out field value as in the latest updated contact.

 

Both approaches are giving compiling error. Any help will be greatly appreciated.

 

Thank you!!!!

 

Error are pointed to the lines in red texts.

 

APPROACH 1

 Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Contact> at line 34 column 4

 

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<Contact>{
// declaring the variable
global final String query;

/* Constructor method to fetch contacts from the database*/

global UpdateEmailOptOutFieldBatchable(){
query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT';
}

/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
List <Contact> ContactsToUpdate = new List<Contact>();
Set <String> ContactIDsToUpdate = new Set<String>();
//Gathering the records, with same email address and different ID, in the list
for(Contact C1: allContactList)
{
List <Contact> emailgroupContactList = new List <Contact> ();
emailgroupContactList.add(C1);
for(Contact C2: allContactList)
{
If (C1.email == C2.email && C1.Id != C2.Id)
{
emailgroupContactList.add(C2);
}
}
// Sorting the groupContactList in terms of Last Modified Date such that the Contact with recent modified date will be at the top.
if(emailgroupContactList.isEmpty == False)
{
for(integer i=0; i<emailgroupContactList.size()-1; i++)
{
for(integer j=0; j<emailgroupContactList.size()-1; j++)
{
If (emailgroupContactList[j].Id != emailgroupContactList[j+1].Id && emailgroupContactList[j].LastModifiedDate < emailgroupContactList[j+1].LastModifiedDate)
{
Contact Temp = new Contact();
Temp = emailgroupContactList[j];
emailgroupContactList[j] = emailgroupContactList[j+1];
emailgroupContactList[j+1] = Temp;
}
}
}
// take HasOptOut Field value of the top most record and update it to the rest of duplicate records in emailgroupContactList
// And then update it to ContactsToUpdate

for(integer i=1; i<emailgroupContactList.size()-1; i++)
{
emailgroupContactList[i].HasOptedOutOfEmail = emailgroupContactList[0].HasOptedOutOfEmail;
if(ContactIDsToUpdate.contains(emailgroupContactList[i].Id)==False)
{
ContactIDsToUpdate.add(emailgroupContactList[i].Id);
ContactsToUpdate.add(emailgroupContactList[i]);
}
}
}
}
If (ContactsToUpdate.isempty==False)
{
update ContactsToUpdate;
}
}

global void finish(Database.BatchableContext BC){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddress(new String[]{'rk@gmail.com'});
mail.setReplyTo('rk@gmail.com');
mail.setSenderDisplayName('Batch Processing');
mail.setSubject('Batch Process Completed');
mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
}
}

 

APPROACH 2

Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Contact> at line 33 column 21

 

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<Contact>{
// declaring the variable
global final String query;

/* Constructor method to fetch contacts from the database*/

global UpdateEmailOptOutFieldBatchable(){
query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT ORDER BY LastModifiedDate DESC';
}

/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
List <Contact> ContactsToUpdate = new List<Contact>();
Set <String> ContactIDsToUpdate = new Set<String>();
for(integer i=0; i<allContactList.size()-1; i++)
{
for(integer j=i+1; j<allContactList.size()-1; j++)
{
If (allContactList[i].email == allContactList[j].email && ContactIDsToUpdate.contains(allContactList[j].Id)==False)
{
ContactIDsToUpdate.add(allContactList[j].Id);
allContactList[j].HasOptedOutOfEmail=allContactList[i].HasOptedOutOfEmail;
ContactsToUpdate.add(allContactList[j]);
}
}
}
If (ContactsToUpdate.isempty==False)
{
update ContactsToUpdate;
}
}
global void finish(Database.BatchableContext BC){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddress(new String[]{'rk@gmail.com'});
mail.setReplyTo('rk@gmail.com');
mail.setSenderDisplayName('Batch Processing');
mail.setSubject('Batch Process Completed');
mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
}
}

 

If possible, could anyone please direct me towards the right direction? The second code (Batch Apex) is just not compiling. Currently the error is,

Error: Compile Error: Invalid type: updateContactOnEmailOptOutChangeScheduler at line 63 column 73

 

 

 

 

Original Trigger Code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

trigger updateContactOnEmailOptOutChange on Contact (after update) {                                                                                          
     
    //Initialize lists and maps

    List<Contact> duplicateContacts = new List<Contact>();
    Map<String, Contact> contactEmailMap = new Map<String, Contact>();
    Map<Id, Contact> contactIdMap = new Map<Id, Contact>();

    //Build a map with contacts to update. Only select the ones that have a different "Email Opt Out" value from the contact being updated.

    for (Integer i = 0; i < Trigger.new.size(); i++) {
        if (Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail) {
            contactEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
            contactIdMap.put(Trigger.old[i].id, Trigger.new[i]);        
        }
    }    
    
    //Only go through this process if "Email Opt Out" (HasOptedOutofEmail) was updated.
    
    If (contactIdMap.size()>0) {
    
        //Query the database and look for all contacts with a duplicate email address (same email as the contact currently being updated).

        for (Contact dupContact : [SELECT Id, Name, Email, HasOptedOutOfEmail
                                   FROM Contact
                                   WHERE Email IN : contactEmailMap.KeySet()
                                   AND Id NOT IN : contactIdMap.KeySet()]) {
            Contact contact = contactEmailMap.get(dupContact.Email);
            If (dupContact.HasOptedOutOfEmail <> contact.HasOptedOutOfEmail) { 
                dupContact.HasOptedOutOfEmail = contact.HasOptedOutOfEmail;   
                duplicateContacts.add(dupContact);
            }
        }    
    
        //If any duplicate contacts were found, update all duplicate contacts with the new HasOptedOutOfEmail value.

       If (duplicateContacts.size()>0) update duplicateContacts;
   }
}

 

Batch Apex

 

global class updateContactOnEmailOptOutChange implements Database.Batchable<sObject>
{
    global string query;
   
    global updateContactOnEmailOptOutChange()
    {
    query = 'SELECT id,Name, Email, HasOptedOutofEmail from Contact where HasOptedOutofEmail=true';
    }
   
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
    return Database.getQueryLocator(query);
    }

   
    global void execute(Database.BatchableContext BC, List <sObject> duplicateContacts)
    {
    Map<String, Contact> contactEmailMap = new Map<String, Contact>();
    Map <Id, Contact> contactIdMap = new Map<Id, Contact>();
   
    // Build a map with contacts to update. Only select the ones that have a different "Email Opt Out" value from the contact being updated.
    if(trigger.isUpdate){

    for(Integer i=0; i<Trigger.new.size();i++)
      {
      if(Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail)
          {
          contactEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
          contactIdMap.put(Trigger.old[i].id, Trigger.new[i]);
          }
      }   
   
    if(contactidMap.size()>0)
    {
    //Query the database and look for all contacts with a duplicate email address(same email as the contact currently being updated)
    for (Contact dupContact: [SELECT Id, Name, Email, HasOptedOutofEmail
                              FROM Contact
                              WHERE Email IN: contactEmailMap.KeySet()
                              AND Id NOT IN: contactIdMap.KeySet()])
                                  {
                                  Contact contact=contactEmailMap.get(dupContact.Email);
                                  If(dupContact.HasOptedOutOfEmail <> contact.HasOptedOutOfEmail)
                                  {
                                  dupContact.HasOptedOutOfEmail = contact.HasOptedOutOfEmail;
                                  duplicateContacts.add(dupContact);
                                  }
                                  }
    // if any duplicate contacts were found, update all duplicate contacts with the new HasOptedOutOFEmail value.
   
    If(duplicateContacts.size<>0) update duplicateContacts;
    }
    }
    }
   
    //The batch process has completed successfully. Schedule next batch.
   
    global void finish(Database.BatchableContext BC){
    // //Build the system time of now + 300 seconds to schedule the batch apex.
    Datetime sysTime = System.now();
    sysTime = sysTime.addSeconds(300);
    String chron_exp=''+sysTime.second()+''+sysTime.minute()+''+sysTime.hour()+''+sysTime.day()+''+sysTime.month()+'?'+sysTime.year();
    system.debug(chron_exp);
    updateContactOnEmailOptOutChangeScheduler scheduleFieldUpdate = new updateContactOnEmailOptOutChangeScheduler();
    //Schedule the next job, and give it the system time so name is unique
    System.schedule('New Email Update Job'+sysTime.getTime(),chron_exp,scheduleFieldUpdate);
    }
    }

 

Hello all,

 

I was wondering if there is any way to modify the following query to limit the results to only  records that were updated after the last batch job 'EmailBatch'  was either ran or completed?

 

query = 'select id,email,hasoptedoutofemail,lastmodifieddate from contact order by email asc,lastmodifieddate asc'; 

The query is currently being used in the start method of a batch apex and I have been constantly receiving following error. (Note I scheduled this job couple of days ago at a particular time and the error was displayed. Next day, the batch was processed perfectly. And again the error occurs today.)

 

First error: SQLException [java.sql.SQLException: ORA-01013: user requested cancel of current operation
: select /*ApexBatch.Class.EmailOptOutBatch.start: line 26*/ *
from (select "Id"
from (select upper(t.email) "_SORT_COL_0",
t.last_update "LastModif...

 

Thanks for your time!!

Hi All.

 

In our organization we have a Task object consisting of 8 million records. Our ultimate task is to change the Last Modified Date(After opening up the field from SFDC support) in activities of the millions of records that were initially imported to SFDC from the previous system. Now, I cannot even do a query to get the exact number of records we're trying to export/import because it always times out.

 

The only criteria we have is OldSystem_Action_Id ! = null which separates the records originated in the old system.

 

I was thinking if we could utilize the batch functionality to break down the processes through the Apex Data Loader. If so, are you aware of any step by step procedures on how I can utilize this methodology. Also, will it be possible to extract the millions of records in separate files?

 

Any help is appreciated! Thanks in advance.

All,

I need to develop a webservice, which will be called in a trigger after some field update. This webservice should send the email to my personal email address. Could someone guide me with the steps required to complete this mini-project?

 

Thanks!!!

 

Hi,

 

i have person account enabled for my Account object. i am trying to update account records but getting error as below

 

INVALID_FIELD_FOR_INSERT_UPDATE, Account: bad field names on insert/update call: Do_Not_Call__pc, wxadmsfapp__UHNW__pc, Head_of_Household__pc, U_S_Citizenship__pc: [Do_Not_C..

 

please let me know what is the problem . i am unable to understand what the error is. i dont have any idea about "Person Account" as well.

 

Thanks in advance 

 

Regards

Rakesh

Below is the Test Class for the Batch class in the following snippet of the code. The test coverage stops right here : global Database.QueryLocator start(Database.BatchableContext BC){

In need of guidance and help.

 

TEST CLASS

@isTest(SeeAllData =true)

    private class UpdateEmailOptOutFieldBatchableTest{
    
    static testmethod void testUpdateEmailOptOutFieldBatchable() {
        
       
    
        Contact ConObj1 = new Contact();
        ConObj1.FirstName = 'Paul';
        ConObj1.LastName = 'McCartney';
        ConObj1.Email='PM@p.com';
        //ConObj1.Id ='0038000001HeyJuDEE';
        ConObj1.HasOptedOutOfEmail=False;
        //ConObj1.LastModifiedDate = 
        insert conObj1;
        
        Contact ConObj2 = new Contact();
        ConObj2.FirstName = 'John';
        ConObj2.LastName = 'Lennon';
        ConObj2.Email='PM@p.com';
        //ConObj2.Id ='0038000002ImaGiNEE';
        ConObj2.HasOptedOutOfEmail=False;
        //ConObj2.LastModifiedDate = 
        insert conObj2;
            
        Contact ConObj3 = new Contact();
        ConObj3.FirstName = 'Ringo';
        ConObj3.LastName = 'Star';
        ConObj3.Email='RS@p.com';
        //ConObj3.Id ='0038000003LsdSkYEE';
        ConObj3.HasOptedOutOfEmail=False;
        //ConObj3.LastModifiedDate = 
        insert conObj3;
        
        Contact ConObj4 = new Contact();
        ConObj4.FirstName = 'George';
        ConObj4.LastName = 'Harrison';
        ConObj4.Email='RS@p.com';
        //ConObj4.Id ='0038000004GenTlYEE';
        ConObj4.HasOptedOutOfEmail=True;
        //ConObj4.LastModifiedDate = 
        insert conObj4;

        Contact ConObj5 = new Contact();
        ConObj5.FirstName = 'Led';
        ConObj5.LastName = 'Zeppelin';
        ConObj5.Email='LZ@p.com';
        //ConObj5.Id ='0038000004HeaVeNNN';
        ConObj5.HasOptedOutOfEmail=False;
        //ConObj5.LastModifiedDate = 
        insert conObj5;

        Contact ConObj6 = new Contact();
        ConObj6.FirstName = 'Jimi';
        ConObj6.LastName = 'Hendrix';
        ConObj6.Email='LZ@p.com';
        //ConObj6.Id ='0038000004CasTlEEE';
        ConObj6.HasOptedOutOfEmail=True;
        //ConObj6.LastModifiedDate = 
        insert conObj6;
        
        List<Contact> ContactListall = new List<Contact>();
        ContactListall.add(conObj1);
        ContactListall.add(conObj2);
        ContactListall.add(conObj3);
        ContactListall.add(conObj4);
        ContactListall.add(conObj5);
        ContactListall.add(conObj6);
 
         Test.startTest();
         //String query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT'; 
         //UpdateEmailOptOutFieldBatchable objUpdateEmailOptOutFieldBatchable = new UpdateEmailOptOutFieldBatchable(query);
         UpdateEmailOptOutFieldBatchable objUpdateEmailOptOutFieldBatchable = new UpdateEmailOptOutFieldBatchable();
         ID batchprocessid = Database.executeBatch(objUpdateEmailOptOutFieldBatchable);
         System.abortJob(batchprocessid);
         Test.stopTest(); 
          }
}

 

BATCH CLASS

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<sObject>{
// declaring the variable
global final String query;
 
/* Constructor method to fetch contacts from the database*/
 
global UpdateEmailOptOutFieldBatchable(){
    query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT ORDER BY LastModifiedDate DESC';
}
 
/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
    return Database.getQueryLocator(query);
}
 
global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
                List <Contact> ContactsToUpdate = new List<Contact>();
                Set <String> ContactIDsToUpdate = new Set<String>();
                for(integer i=0; i<allContactList.size()-1; i++)
                {
                                for(integer j=i+1; j<allContactList.size()-1; j++)
                                {
                                                If (allContactList[i].email == allContactList[j].email && ContactIDsToUpdate.contains(allContactList[j].Id)==False)
                                                {
                                                                ContactIDsToUpdate.add(allContactList[j].Id);
                                                                allContactList[j].HasOptedOutOfEmail=allContactList[i].HasOptedOutOfEmail;
                                                                ContactsToUpdate.add(allContactList[j]);
                                                }
                                }
                }             
                If (ContactsToUpdate.isempty()==False)
                {
                                update ContactsToUpdate;
                }
}
global void finish(Database.BatchableContext BC){
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    mail.setToAddresses(new String[]{'rkshrest@gmail.com'});
    mail.setReplyTo('rkshrest@gmail.com');
    mail.setSenderDisplayName('Batch Processing');
    mail.setSubject('Batch Process Completed');
    mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }
}

Hi All,

 

Following are the two approaches to find the contacts with same email value as the contact record that was latest updated and provide the duplicate contacts the same Email Opt Out field value as in the latest updated contact.

 

Both approaches are giving compiling error. Any help will be greatly appreciated.

 

Thank you!!!!

 

Error are pointed to the lines in red texts.

 

APPROACH 1

 Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Contact> at line 34 column 4

 

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<Contact>{
// declaring the variable
global final String query;

/* Constructor method to fetch contacts from the database*/

global UpdateEmailOptOutFieldBatchable(){
query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT';
}

/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
List <Contact> ContactsToUpdate = new List<Contact>();
Set <String> ContactIDsToUpdate = new Set<String>();
//Gathering the records, with same email address and different ID, in the list
for(Contact C1: allContactList)
{
List <Contact> emailgroupContactList = new List <Contact> ();
emailgroupContactList.add(C1);
for(Contact C2: allContactList)
{
If (C1.email == C2.email && C1.Id != C2.Id)
{
emailgroupContactList.add(C2);
}
}
// Sorting the groupContactList in terms of Last Modified Date such that the Contact with recent modified date will be at the top.
if(emailgroupContactList.isEmpty == False)
{
for(integer i=0; i<emailgroupContactList.size()-1; i++)
{
for(integer j=0; j<emailgroupContactList.size()-1; j++)
{
If (emailgroupContactList[j].Id != emailgroupContactList[j+1].Id && emailgroupContactList[j].LastModifiedDate < emailgroupContactList[j+1].LastModifiedDate)
{
Contact Temp = new Contact();
Temp = emailgroupContactList[j];
emailgroupContactList[j] = emailgroupContactList[j+1];
emailgroupContactList[j+1] = Temp;
}
}
}
// take HasOptOut Field value of the top most record and update it to the rest of duplicate records in emailgroupContactList
// And then update it to ContactsToUpdate

for(integer i=1; i<emailgroupContactList.size()-1; i++)
{
emailgroupContactList[i].HasOptedOutOfEmail = emailgroupContactList[0].HasOptedOutOfEmail;
if(ContactIDsToUpdate.contains(emailgroupContactList[i].Id)==False)
{
ContactIDsToUpdate.add(emailgroupContactList[i].Id);
ContactsToUpdate.add(emailgroupContactList[i]);
}
}
}
}
If (ContactsToUpdate.isempty==False)
{
update ContactsToUpdate;
}
}

global void finish(Database.BatchableContext BC){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddress(new String[]{'rk@gmail.com'});
mail.setReplyTo('rk@gmail.com');
mail.setSenderDisplayName('Batch Processing');
mail.setSubject('Batch Process Completed');
mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
}
}

 

APPROACH 2

Error: Compile Error: Initial term of field expression must be a concrete SObject: LIST<Contact> at line 33 column 21

 

global Class UpdateEmailOptOutFieldBatchable implements Database.Batchable<Contact>{
// declaring the variable
global final String query;

/* Constructor method to fetch contacts from the database*/

global UpdateEmailOptOutFieldBatchable(){
query = 'SELECT Id, Name, Email, HasOptedOutOfEmail, LastModifiedDate from CONTACT ORDER BY LastModifiedDate DESC';
}

/*Start method to be invoked*/
global Database.QueryLocator start(Database.BatchableContext BC){
return Database.getQueryLocator(query);
}

global void execute(Database.BatchableContext BC, List<Contact> allContactList)
{
// declaring the variables
List <Contact> ContactsToUpdate = new List<Contact>();
Set <String> ContactIDsToUpdate = new Set<String>();
for(integer i=0; i<allContactList.size()-1; i++)
{
for(integer j=i+1; j<allContactList.size()-1; j++)
{
If (allContactList[i].email == allContactList[j].email && ContactIDsToUpdate.contains(allContactList[j].Id)==False)
{
ContactIDsToUpdate.add(allContactList[j].Id);
allContactList[j].HasOptedOutOfEmail=allContactList[i].HasOptedOutOfEmail;
ContactsToUpdate.add(allContactList[j]);
}
}
}
If (ContactsToUpdate.isempty==False)
{
update ContactsToUpdate;
}
}
global void finish(Database.BatchableContext BC){
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddress(new String[]{'rk@gmail.com'});
mail.setReplyTo('rk@gmail.com');
mail.setSenderDisplayName('Batch Processing');
mail.setSubject('Batch Process Completed');
mail.setPlainTextBody('Batch Process of Email Opt Out field update for duplicate contact records has completed');
Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
}
}

 

If possible, could anyone please direct me towards the right direction? The second code (Batch Apex) is just not compiling. Currently the error is,

Error: Compile Error: Invalid type: updateContactOnEmailOptOutChangeScheduler at line 63 column 73

 

 

 

 

Original Trigger Code

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

trigger updateContactOnEmailOptOutChange on Contact (after update) {                                                                                          
     
    //Initialize lists and maps

    List<Contact> duplicateContacts = new List<Contact>();
    Map<String, Contact> contactEmailMap = new Map<String, Contact>();
    Map<Id, Contact> contactIdMap = new Map<Id, Contact>();

    //Build a map with contacts to update. Only select the ones that have a different "Email Opt Out" value from the contact being updated.

    for (Integer i = 0; i < Trigger.new.size(); i++) {
        if (Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail) {
            contactEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
            contactIdMap.put(Trigger.old[i].id, Trigger.new[i]);        
        }
    }    
    
    //Only go through this process if "Email Opt Out" (HasOptedOutofEmail) was updated.
    
    If (contactIdMap.size()>0) {
    
        //Query the database and look for all contacts with a duplicate email address (same email as the contact currently being updated).

        for (Contact dupContact : [SELECT Id, Name, Email, HasOptedOutOfEmail
                                   FROM Contact
                                   WHERE Email IN : contactEmailMap.KeySet()
                                   AND Id NOT IN : contactIdMap.KeySet()]) {
            Contact contact = contactEmailMap.get(dupContact.Email);
            If (dupContact.HasOptedOutOfEmail <> contact.HasOptedOutOfEmail) { 
                dupContact.HasOptedOutOfEmail = contact.HasOptedOutOfEmail;   
                duplicateContacts.add(dupContact);
            }
        }    
    
        //If any duplicate contacts were found, update all duplicate contacts with the new HasOptedOutOfEmail value.

       If (duplicateContacts.size()>0) update duplicateContacts;
   }
}

 

Batch Apex

 

global class updateContactOnEmailOptOutChange implements Database.Batchable<sObject>
{
    global string query;
   
    global updateContactOnEmailOptOutChange()
    {
    query = 'SELECT id,Name, Email, HasOptedOutofEmail from Contact where HasOptedOutofEmail=true';
    }
   
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
    return Database.getQueryLocator(query);
    }

   
    global void execute(Database.BatchableContext BC, List <sObject> duplicateContacts)
    {
    Map<String, Contact> contactEmailMap = new Map<String, Contact>();
    Map <Id, Contact> contactIdMap = new Map<Id, Contact>();
   
    // Build a map with contacts to update. Only select the ones that have a different "Email Opt Out" value from the contact being updated.
    if(trigger.isUpdate){

    for(Integer i=0; i<Trigger.new.size();i++)
      {
      if(Trigger.old[i].HasOptedOutOfEmail != Trigger.new[i].HasOptedOutOfEmail)
          {
          contactEmailMap.put(Trigger.old[i].email, Trigger.new[i]);
          contactIdMap.put(Trigger.old[i].id, Trigger.new[i]);
          }
      }   
   
    if(contactidMap.size()>0)
    {
    //Query the database and look for all contacts with a duplicate email address(same email as the contact currently being updated)
    for (Contact dupContact: [SELECT Id, Name, Email, HasOptedOutofEmail
                              FROM Contact
                              WHERE Email IN: contactEmailMap.KeySet()
                              AND Id NOT IN: contactIdMap.KeySet()])
                                  {
                                  Contact contact=contactEmailMap.get(dupContact.Email);
                                  If(dupContact.HasOptedOutOfEmail <> contact.HasOptedOutOfEmail)
                                  {
                                  dupContact.HasOptedOutOfEmail = contact.HasOptedOutOfEmail;
                                  duplicateContacts.add(dupContact);
                                  }
                                  }
    // if any duplicate contacts were found, update all duplicate contacts with the new HasOptedOutOFEmail value.
   
    If(duplicateContacts.size<>0) update duplicateContacts;
    }
    }
    }
   
    //The batch process has completed successfully. Schedule next batch.
   
    global void finish(Database.BatchableContext BC){
    // //Build the system time of now + 300 seconds to schedule the batch apex.
    Datetime sysTime = System.now();
    sysTime = sysTime.addSeconds(300);
    String chron_exp=''+sysTime.second()+''+sysTime.minute()+''+sysTime.hour()+''+sysTime.day()+''+sysTime.month()+'?'+sysTime.year();
    system.debug(chron_exp);
    updateContactOnEmailOptOutChangeScheduler scheduleFieldUpdate = new updateContactOnEmailOptOutChangeScheduler();
    //Schedule the next job, and give it the system time so name is unique
    System.schedule('New Email Update Job'+sysTime.getTime(),chron_exp,scheduleFieldUpdate);
    }
    }