I am writing a batch method for a client that just updates a couple of field based on the date. I used this example as a guide.
Here's my code:
global class BatchUpdateFiscalMonth implements Database.Batchable<SObject>, Database.Stateful{
Double failedUpdates{get; set;}
global BatchUpdateFiscalMonth(){
failedUpdates = 0;
}
global Database.queryLocator start(Database.BatchableContext ctx){
return Database.getQueryLocator([SELECT id, Current_Fiscal_Month__c, Current_Fiscal_Month_Value__c, Invoice_Date__c, ACK_Date__c, Fiscal_Month_Text__c, RecordType.Id FROM Invoice_Order__c]);
}
global void execute(Database.BatchableContext ctx, List<Sobject> scope){
RecordType invoiceType = [SELECT id FROM RecordType WHERE sObjectType = 'Invoice_Order__c' AND Name = 'Invoice'];
RecordType orderType = [SELECT id FROM RecordType WHERE sObjectType = 'Invoice_Order__c' AND Name = 'Order'];
List<Invoice_Order__c> invOrds = (List<Invoice_Order__c>)scope;
for(Integer i = 0; i < invOrds.size(); i++){
invOrds[i].Current_Fiscal_Month_Value__c = String.valueOf(fiscalMonths.getCurrentFiscalMonth());
if(invOrds[i].RecordType.Id == invoiceType.id){
invOrds[i].Fiscal_Month_Text__c = String.valueOf(fiscalMonths.getFiscalMonth(invOrds[i].Invoice_Date__c));
}
if(invOrds[i].RecordType.Id == orderType.id){
invOrds[i].Fiscal_Month_Text__c = String.valueOf(fiscalMonths.getFiscalMonth(invOrds[i].ACK_Date__c));
}
}
List<Database.saveResult> dsrs = Database.update(invOrds, false);
for(Database.SaveResult dsr : dsrs){
if(!dsr.isSuccess()){
failedUpdates++;
}
}
}
global void finish(Database.BatchableContext ctx){
AsyncApexJob a = [SELECT id, ApexClassId,
JobItemsProcessed, TotalJobItems,
NumberOfErrors, CreatedBy.Email
FROM AsyncApexJob
WHERE id = :ctx.getJobId()];
String emailMessage = 'Your batch job '
+ 'BatchUpdateFiscalMonth '
+ 'has finished. It executed '
+ a.totalJobItems
+ ' batches. Of which, ' + a.jobitemsprocessed
+ ' processed without any exceptoins thrown and '
+ a.numberOfErrors
+ ' batches threw unhandled exceptions.'
+ ' Of the batches that executed without error, '
+ failedUpdates
+ ' records were not updated successfully.';
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
String[] toAddresses = new String[] {'email@domain.com'};
mail.setToAddresses(toAddresses);
mail.setReplyTo('noreply@salesforce.com');
mail.setSubject('Batch job completed');
mail.setPlainTextBody(emailMessage);
mail.setHtmlBody(emailMessage);
Messaging.sendEmail(new Messaging.SingleEmailMessage[]{ mail });
}
public static testMethod void TestBatchUpdateFiscalMonth(){
//create the test data
RecordType invoiceType = [SELECT Id FROM RecordType WHERE sObjectType = 'Invoice_Order__c' AND Name = 'Invoice'];
RecordType orderType = [SELECT Id FROM RecordType WHERE sObjectType = 'Invoice_Order__c' AND Name = 'Order'];
Account testAccount = new Account(Name='Test');
insert testAccount;
List<Invoice_Order__c> invoices = new List<Invoice_Order__c>();
List<Invoice_Order__c> orders = new List<Invoice_Order__c>();
for(Integer i=0;i<10;i++){
Invoice_Order__c inv = new Invoice_Order__c(RecordType=invoiceType,Invoice_Date__c=Date.Today(),Account__c=testAccount.Id);
invoices.add(inv);
Invoice_Order__c ord = new Invoice_Order__c(RecordType=orderType,ACK_Date__c=Date.Today(),Account__c=testAccount.Id);
orders.add(ord);
}
insert invoices;
insert orders;
// do the test
Test.startTest();
Database.executeBatch(new BatchUpdateFiscalMonth());
Test.stopTest();
// Verify the test results
invoices = [SELECT Invoice_Date__c, Current_Fiscal_Month_Value__c,Fiscal_Month_Text__c FROM Invoice_Order__c WHERE Id IN :invoices];
for(Invoice_Order__c io: invoices){
System.assertEquals(io.Fiscal_Month_Text__c,String.valueOf(fiscalMonths.getFiscalMonth(io.Invoice_Date__c)));
System.assertEquals(io.Current_Fiscal_Month_Value__c,String.valueOf(fiscalMonths.getCurrentFiscalMonth()));
}
orders = [SELECT ACK_Date__c,Fiscal_Month_Text__c, Current_Fiscal_Month_Value__c FROM Invoice_Order__c WHERE Id IN :orders];
for(Invoice_Order__c io: orders){
System.assertEquals(io.Current_Fiscal_Month_Value__c,String.valueOf(fiscalMonths.getCurrentFiscalMonth()));
System.assertEquals(io.Fiscal_Month_Text__c,String.valueOf(fiscalMonths.getFiscalMonth(io.ACK_Date__c)),io.ACK_Date__c);
}
}
}
I have tried running the statements in the APEX execute anonymous window, and they all succeed done that way. Every time it results in an email message that says:
Your batch job BatchUpdateFiscalMonth has finished. It executed 1 batches. Of which, 1 processed without any exceptoins thrown and 0 batches threw unhandled exceptions. Of the batches that executed without error, 2.0 records were not updated successfully.
There was nothing in the logs that was helpful. I don't know how to diagnose this. I'm at a total loss here.