function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Tom SimmonsTom Simmons 

Help with Test Class on Batch Apex


All, need help with test class on Batch apex. Below is batch apex code which make 2 callouts (for Token and actual data) however i`m not able to get test coverege on this class. All I have is 7% coverage. Can someone please help?
 
global class CalloutsAccounts implements Database.Batchable<sObject>,Database.AllowsCallouts{


   global Database.QueryLocator start(Database.BatchableContext BC){
        String query =  'SELECT Id FROM Account LIMIT 1';
        return Database.getQueryLocator(query); 
   }

   global void execute(Database.BatchableContext BC, List<Account> scope){
        HttpRequest obj = new HttpRequest();
        HttpResponse res = new HttpResponse();
        Http http = new Http();
        String reqBody = '{ "user": "Username", "passwd": "user_password" }';
        obj.setMethod('POST');
        obj.setHeader('Content-Type','application/json');
        obj.setEndPoint('https://test.samplepoint.com/api/UserSrvs.svc/Login');
        obj.setBody(reqBody);
        obj.getheader('Auth-Token');
        res = http.send(obj);

                authtoken objAuthenticationInfo = (authtoken)JSON.deserialize(res.getbody(), authtoken.class);
String token = res.getHeader('Auth-Token');


        Http h1 = new Http();
        HttpRequest req1 = new HttpRequest();
        String reqBody2 = ' {"Accountype" : "workforce"}'; 
        req1.setHeader('Auth-Token', token);
        req1.setHeader('Content-Type','application/json');
        req1.setMethod('POST');
         req1.setBody(reqBody2);

        req1.setEndpoint('https://test.samplepoint.com/api/accservices.svc/accountfeed');
        HttpResponse res1 = h1.send(req1);



                   JSONParser parser = JSON.createParser(res1.getBody());
                    parser.nextToken();
                     parser.nextValue();

                    String fieldName = parser.getCurrentName();
                    String fieldValue = parser.getText(); 

    accParser deserializeResults3 =  new accParser ();
    deserializeResults3 = (accParser)System.JSON.deserialize(fieldValue, accParser.class);
     List < accParser.cls_account> advisorList = new List< accParser.cls_account>();
    advisorList = deserializeResults3.root.accounts.account;

           Map <Decimal,Id> AdvisorMap = New Map  <Decimal,Id>   ();

        List <Account> advisorAccList = [SELECT Id, Fact_ID__c, RecordTypeID FROM Account WHERE RecordTypeid = '0124100000091Ho'];

        For (Account Acs : advisorAccList) {
            If (Acs.Fact_ID__c != null)
            AdvisorMap.put(Acs.Fact_ID__c, Acs.ID);
                }


             Map <String,Id> HouseholdMap = New Map  <String,Id>   ();

        List <Account> advisorAccList1 = [SELECT Id, SSCN__c, RecordTypeID FROM Account WHERE RecordTypeid = '012410000009Il6'];

        For (Account Acs1 : advisorAccList1) {
            If (Acs1.SSCN__c != null)
            HouseholdMap.put(Acs1.SSCN__c, Acs1.ID);
            system.debug('@@@'+HouseholdMap);
                }



List<Financial_Account__c> lstAccount = new List<Financial_Account__c>();
for(accountParser.cls_account cand : advisorList){
    Financial_Account__c PFA = New Financial_Account__c();
    //PFA.Cirrus_Unique_ID__c =  cand.account_id;

    //Map Advisor Lookup
   PFA.Advisor_ID__c = cand.advisor_id; 
   PFA.Advisor__c = AdvisorMap.get(PFA.Advisor_ID__c );  

    //Map Household Client Lookup
    PFA.Household_ID2__c = cand.household_id;
   if (HouseholdMap.get(PFA.Household_ID2__c) == null) {
       PFA.Client__c = '0013C000003Ywet'; 
} else if (PFA.Household_ID2__c != null) {
         PFA.Client__c = HouseholdMap.get(PFA.Household_ID2__c);  
}




    PFA.Unique_ID__c =  cand.account_id;
    PFA.Financial_Account_Number__c =  cand.accountnum;
    PFA.Account_Type__c =  cand.account;
    PFA.Tax_Status__c=  cand.taxablestatus;
    PFA.Investment_Objective__c =  cand.objective;
    if (cand.inception_date != null) {
    PFA.Account_Opening__c = date.parse(cand.inception);
        }
        if (cand.perf_begin_date != null) {
    PFA.perf_begin_date__c = date.parse(cand.perfdate);
        }
    // if (cand.household_id != null) {
  //  PFA.Household_ID__c = cand.housedate_id;
  //      }
    PFA.Account_Type__c =  cand.account_type;
   // PFA.Client__c =  '0013C000003CRTr'; LOOKUP TO ACCOUNTS
    PFA.compute_flg__c = cand.compute_flg;
    PFA.Account_Description__c = cand.description;
    PFA.fwc_hh_id__c = cand.fwc_hh_id;
        if (cand.termination_date != null) {
    PFA.termination_date__C = date.parse(cand.termination_date);
        }
        if (cand.last_date != null) {
    PFA.last_date__c = date.parse(cand.last_date);
        }
    PFA.Custodian_Id__c = cand.custodian_id;
    PFA.billing_account_num__c = cand.billing_account_num;
    PFA.rebal_method__c = cand.rebal_method;




    lstAccount.add(PFA);
}


Boolean isUpsertfirstTime = true;
try {
    upsert lstAccount Financial_Account_Number__c;
}catch (DMLException e) {
                System.debug('Re-trying');
                if(isUpsertfirstTime){
                        upsert lstAccount Financial_Account_Number__c;
                                isUpsertfirstTime = false;
              }
}


   }       

   global void finish(Database.BatchableContext BC){
              CalloutsAccounts2 myaccBatch = new CalloutsAccounts2();
      Id batchProcessId = Database.executeBatch(myacctBatch);

   }
}

Mock:
 
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
    // Implement this interface method
    global HTTPResponse respond(HTTPRequest req) {
        // Optionally, only send a mock response for a specific endpoint
        // and method.
               System.assertEquals('https://test.samplepoint.com/api/UserSrvs.svc/', req.getEndpoint());
        System.assertEquals('POST', req.getMethod()); 

        // Create a fake response
        HttpResponse res = new HttpResponse();
        res.setHeader('Content-Type', 'application/json');
res.setBody(''{ "user": "Username", "passwd": "user_password" }');
        res.setHeader('Auth-Token', '3+yV8B+7iSTu7Oj4alK4/fJPY1a5VRhAre6jG5vx6kDTXMOENFWJqAIQpuYE8nOdLwDmQBdo=');
 res.setStatusCode(200);         
        return res;
    }
}

Test class:
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
        // Set mock callout class 

        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Test.startTest();
  Account acc = new Account(  Name = 'My Test Account' );

  		  upsert acc;

        Database.executeBatch(new CalloutsAccounts(), 100);
        Test.stopTest();

    }


 
Best Answer chosen by Tom Simmons
karthikeyan perumalkarthikeyan perumal
Hello, 

Update your Moke Test class like below:  

Note you have to form  Serilized JSON String as per your Wrapper Class "accParser" also for your reference here is the Formate from log and replace the JSON in to  response string variable in MockHttpResponseGenerator  this class. 

User-added image


Look @ the parameter and pass it accordingly. then your test class will be passed and get decent code coverage. 
 
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
        
    global HTTPResponse respond(HTTPRequest req) {
        // Optionally, only send a mock response for a specific endpoint
        // and method.
       if(req.getBody().contains('user_password'))
       {
        System.assertEquals('https://test.samplepoint.com/api/UserSrvs.svc/Login', req.getEndpoint());
         HttpResponse res = new HttpResponse();
        String response='{"user": "Username", "passwd": "user_password"}';
        res.setHeader('Content-Type', 'application/json');
        res.setBody(response);
        res.setHeader('Auth-Token', '3+yV8B+7iSTu7Oj4alK4/fJPY1a5VRhAre6jG5vx6kDTXMOENFWJqAIQpuYE8nOdLwDmQBdo='); 
        res.setStatusCode(200);         
        return res;
        }
        else
        {
        System.assertEquals('https://test.samplepoint.com/api/accservices.svc/accountfeed', req.getEndpoint());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        String response='{"Accountype" : "workforce"}';
        res.setHeader('Content-Type', 'application/json');
        res.setBody(response);
        res.setHeader('Auth-Token', '3+yV8B+7iSTu7Oj4alK4/fJPY1a5VRhAre6jG5vx6kDTXMOENFWJqAIQpuYE8nOdLwDmQBdo='); 
        res.setStatusCode(200);         
       return res;
    }
    
}
}

And Test class should be like below: 
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
      Test.startTest();
     
     Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
       
       CalloutsAccounts CA= new CalloutsAccounts ();
       Account acc = new Account( Name = 'My Test Account' );
       Insert acc;
        Database.executeBatch(new CalloutsAccounts(), 100);
       Test.stopTest();

    }
    }


Thanks
karthik
 

All Answers

karthikeyan perumalkarthikeyan perumal
Hello 

Use below code, 
 
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
        CalloutsAccounts CA= new CalloutsAccounts ();

        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        Test.startTest();
  Account acc = new Account( Name = 'My Test Account' );

  		  Insert acc;

        Database.executeBatch(new CalloutsAccounts(), 100);
        Test.stopTest();

    }

if above code is not covered use below code: 
 
@isTest
public class CalloutClassTest {
    static testMethod void testCallout() {
        Database.QueryLocator QL;
        Database.BatchableContext BC;
        List<Account> AcctList = new List<Account>();
        CalloutsAccounts  AU = new CalloutsAccounts ('Name', 'Test');
        QL = AU.start(bc);
       
        Database.QueryLocatorIterator QIT =  QL.iterator();
        while (QIT.hasNext())
        {
            Account Acc = (Account)QIT.next();           
            System.debug(Acc);
            AcctList.add(Acc);
        }  
        Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
        AU.execute(BC, AcctList);
        AU.finish(BC);       
    }
}


Hope this will help you,

If its not covered, 

just post your not covered code here. 

Thanks
karthik

 
Tom SimmonsTom Simmons
Thanks Karthikeyan...  I think code 1 that you have posted is working well and it increased a code coverage however I`m now getting "System.NullPointerException: Argument 2 cannot be null" error. Can you please help ?
 
Tom SimmonsTom Simmons
Thanks Karthik for all your help. I`m getting this error on line 28 " req1.setHeader('Auth-Token', token);" . Evething before this is getting covered. This code is making two callouts
1) It makes a callout to external system and gets back an authorization token
2) It takes that Authorization token and makes second callout to get the actual JSON data

Hope this helps. Please let me know your thoughts.
karthikeyan perumalkarthikeyan perumal
Hello 

May be " String token = res.getHeader('Auth-Token'); "  token  will be null so that System.NullPointerException thrown. 

Try below code..  if its not covered  kinldy look at below link for same issue. 
 
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
      Test.startTest();
       Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
       CalloutsAccounts CA= new CalloutsAccounts ();
       Account acc = new Account( Name = 'My Test Account' );
       Insert acc;
        Database.executeBatch(new CalloutsAccounts(), 100);
       Test.stopTest();

    }

kinldy refer below  link for same issue.. how to set access token from moke test and pass to test class.. 
http://salesforce.stackexchange.com/questions/144394/rest-api-call-test-class-mock-test

Hope this will help you 
Thanks
karthik
 
Tom SimmonsTom Simmons
Thank you very much Kartik, I believe we are close to the soltion.  I used above code and set a header in mock response and it increased code coverage. However, it is only giving me a coverage till line 46 now. Anything after line 46 is not being covered, how can I fix this.

 
Tom SimmonsTom Simmons
Hi Karthik, Also -  I have updated question here which will give you more information about the problem. https://developer.salesforce.com/forums/?id=9060G000000XdwAQAS
Any help is much appriciated.
karthikeyan perumalkarthikeyan perumal
can you please shre this class "accParser " 

List < accParser.cls_account> advisorList = new List< accParser.cls_account>();

Thanks
karthik
 
Tom SimmonsTom Simmons
Hi Kathik, here is go ...
 
public class accParser{
	public cls_rut root;
	public class cls_rut {
		public cls_pagination pagination;
		public cls_accounts accounts;
	}
	public class cls_pagination {
		public cls_accounts accounts;
		public String page;	//1
		public String pageSize;	//2
	}
	public class cls_accounts {
		public cls_account[] account;
	}
	public class cls_account {
		public String account_id;	//52
		public String account_num;	//20696291
		public String account_type;	//test cass 
		public String taxable_flg;	//1
		public Integer compute;	//0
		public String description;	//afgag awgawg 
		public Integer add_id;	//57
		public String fwc_id;	//awga awgagw
		public String begin_date;	//07/10/2003
		public String inc_date;	//07/09/2003
		public String termination_date;	//02/24/2014
		public String last_date;	//04/30/2008 
		public Decimal test_id;	//18
		public String planning_id;	//175
		public String account_num2;	//20696291
		public String objective;	//www gwagag 
        public Integer rebal_method;	//www gwagag 
		public String	household_id;

	}
	public static accParser parse(String json){
		return (accParser) System.JSON.deserialize(json, accParser.class);
	}

	
}
Appriciate your help!
 
karthikeyan perumalkarthikeyan perumal
also i need this class. "authtoken " Coz i have to create this batch class in my Org and i have to write test class. i will give a try in my Org. so that i able  write a Test class clearly.

Thanks
karthik
 
Tom SimmonsTom Simmons
Here is Authtoken class:
 
//
// Generated by JSON2Apex http://json2apex.herokuapp.com/
//

public class authtoken {
	public static void consumeObject(JSONParser parser) {
		Integer depth = 0;
		do {
			JSONToken curr = parser.getCurrentToken();
			if (curr == JSONToken.START_OBJECT || 
				curr == JSONToken.START_ARRAY) {
				depth++;
			} else if (curr == JSONToken.END_OBJECT ||
				curr == JSONToken.END_ARRAY) { 
				depth--;
			}
		} while (depth > 0 && parser.nextToken() != null);
	}

	public String d {get;set;} 

	public authtoken(JSONParser parser) {
		while (parser.nextToken() != JSONToken.END_OBJECT) {
			if (parser.getCurrentToken() == JSONToken.FIELD_NAME) {
				String text = parser.getText();
				if (parser.nextToken() != JSONToken.VALUE_NULL) {
					if (text == 'd') {
						d = parser.getText();
					} else {
						System.debug(LoggingLevel.WARN, 'Root consuming unrecognized property: '+text);
						consumeObject(parser);
					}
				}
			}
		}
	}
	
	
	public static authtoken parse(String json) {
		return new authtoken(System.JSON.createParser(json));
	}
}

 
Tom SimmonsTom Simmons
My Skype Id is live:t__simmons@123 ... In case u have any additional questions
karthikeyan perumalkarthikeyan perumal
Hello, 

Update your Moke Test class like below:  

Note you have to form  Serilized JSON String as per your Wrapper Class "accParser" also for your reference here is the Formate from log and replace the JSON in to  response string variable in MockHttpResponseGenerator  this class. 

User-added image


Look @ the parameter and pass it accordingly. then your test class will be passed and get decent code coverage. 
 
@isTest
global class MockHttpResponseGenerator implements HttpCalloutMock {
        
    global HTTPResponse respond(HTTPRequest req) {
        // Optionally, only send a mock response for a specific endpoint
        // and method.
       if(req.getBody().contains('user_password'))
       {
        System.assertEquals('https://test.samplepoint.com/api/UserSrvs.svc/Login', req.getEndpoint());
         HttpResponse res = new HttpResponse();
        String response='{"user": "Username", "passwd": "user_password"}';
        res.setHeader('Content-Type', 'application/json');
        res.setBody(response);
        res.setHeader('Auth-Token', '3+yV8B+7iSTu7Oj4alK4/fJPY1a5VRhAre6jG5vx6kDTXMOENFWJqAIQpuYE8nOdLwDmQBdo='); 
        res.setStatusCode(200);         
        return res;
        }
        else
        {
        System.assertEquals('https://test.samplepoint.com/api/accservices.svc/accountfeed', req.getEndpoint());
        // Create a fake response
        HttpResponse res = new HttpResponse();
        String response='{"Accountype" : "workforce"}';
        res.setHeader('Content-Type', 'application/json');
        res.setBody(response);
        res.setHeader('Auth-Token', '3+yV8B+7iSTu7Oj4alK4/fJPY1a5VRhAre6jG5vx6kDTXMOENFWJqAIQpuYE8nOdLwDmQBdo='); 
        res.setStatusCode(200);         
       return res;
    }
    
}
}

And Test class should be like below: 
@isTest
private class CalloutClassTest {
     @isTest static void testCallout() {
      Test.startTest();
     
     Test.setMock(HttpCalloutMock.class, new MockHttpResponseGenerator());
       
       CalloutsAccounts CA= new CalloutsAccounts ();
       Account acc = new Account( Name = 'My Test Account' );
       Insert acc;
        Database.executeBatch(new CalloutsAccounts(), 100);
       Test.stopTest();

    }
    }


Thanks
karthik
 
This was selected as the best answer
Tom SimmonsTom Simmons
Thank you very much Karthik. In mock class above, at which line do I have to pass the correct Serilized JSON String ? Sorry, little confused.
karthikeyan perumalkarthikeyan perumal
Hello Tom , 


 String response='{"user": "Username", "passwd": "user_password"}';

String response='{"Accountype" : "workforce"}';

The above said place you have to pass JSON Serolized string.  i will give easy way to pass that.  Make System.Debug (res1.getBody()); at line 38  in this bathc class"CalloutsAccounts " copy that JSON and past it here in Moke Test class. 

Thanks
karthik
 
karthikeyan perumalkarthikeyan perumal
can you come to skype :

i can't search you..      rajam.karthik      My Id 

Thanks
karthik
 
Tom SimmonsTom Simmons
THANK YOU very much Karthik for all your great help! I got this resolved.
RajanRajan
I need help for a similar test class because I'm unable to solve it,
My batch class is
************************
global class SalesAIChildDataSyncBatch implements Database.Batchable<sObject>, Database.AllowsCallouts, Schedulable{

    global class Item {
        global String status;
        global Integer code;
        global String message;
        global Integer mappingId;
        global String sessionToken;
        global String userType;
        global String name;
        global String emailId;
        global Data data;
        
        global Item(){}
    }
    
    global class Data {
        global Integer dataId;
        global String oppId;
        public String accountNumber;
        public String accountId;
        public String accountName;
        public String contactName;
        public String designation;
        public String status;
        public String type;
        public String email;
        public Integer contactYTDSales;
        public Integer contactLeadScore;
        public Integer leadScore;
        public Integer opportunityScore;
        public String nextBestAction;
        public String productServiceRecommendation;
        public String feedback;
        public Integer thisWeek;
        public Integer lastWeek;
        public String primarySKU;
        public String skuLabel;
        public String CurrencyC;
        public String businessUnit;
        public String mobileNumber;
        public String officeNumber;
        public String productServiceRationale1;
        public Integer productServiceScore1;
        public String productServiceRationale2;
        public Integer productServiceScore2;
        public String productServiceRationale3;
        public String productServiceRationale4;
        public Integer productServiceScore4;
        public String productServiceRationale5;
        public Integer productServiceScore5;
        public String productServiceRationale6;
        public Integer productServiceScore6;
        public String industryType;
        public Date customerSince;
        public String productCheatSheet1;
        public String productCheatSheet2;
        public String productCheatSheet3;
        public String productCheatSheet4;
        public String productCheatSheet5;
        public String productCheatSheet6;
        public String relatedProduct1;
        public String relatedProduct2;
        public String relatedProduct3;
        public String relatedProduct4;
        public String relatedProduct5;
        public String relatedProduct6;
        public String discountGuidance;
        public String location;
        
        public Data(){}
    }

   
   global Database.QueryLocator start(Database.BatchableContext BC){
      Set<Id> accIds = new Set<Id>{'001N000001AJNSi'};
      return Database.getQueryLocator('SELECT Id, AccountNumber, dataId__c, (SELECT Name FROM Contacts ORDER BY CreatedDate DESC LIMIT 1) FROM Account WHERE Id IN : accIds');
   }

   global void execute(Database.BatchableContext BC, List<sObject> scope){
        for(Account acc : (List<Account>) scope){
            String contactName = '';
            
            
            if(acc.Contacts != null && acc.Contacts.size() > 0){
                contactName = acc.Contacts[0].Name;
            }
            String dataId = string.valueof(acc.dataId__c);
            fetchData(acc.Id, dataId);
        }
   }
   
   global void fetchData(Id accId, String dataidAcc){
       navikAuthDomain.response mapResp;
            if(!test.isRunningTest())
             mapResp = navikAuthentication.getMapId(UserInfo.getUserEmail());
        else
            
            {
                mapResp = new navikAuthDomain.response();
                mapResp.sessionToken='121122';
            }
      
        Recommendation__c recomnd;
        Recommendation_Rationale__c recomRational;
        Cheatsheet__c cheatsht;
        
        if(mapResp !=null){
            Http http = new Http();
            HttpRequest request = new HttpRequest();
        
            request.setHeader('sessionToken',mapResp.sessionToken);
            request.setEndpoint('http://35.161.167.154:8080/sales-core/v1.0/sales/recommendation/product_services?');
            request.setMethod('POST');
            
            //accId = EncodingUtil.urlEncode(accId,'UTF-8');
            dataidAcc = EncodingUtil.urlEncode(dataidAcc,'UTF-8');
            //cont = EncodingUtil.urlEncode(cont,'UTF-8');
            String recom = EncodingUtil.urlEncode('true','UTF-8');
            
            request.setBody('dataId='+dataidAcc);
            
            HttpResponse response = http.send(request);
            
                    /*      if(!test.isRunningTest()){
                       
                                response = http.send(request);}
                           else {
                                 response=new HttpResponse();
                    //response = MockApiCalls.WebserviceExpectedResponse();
                                     }
                    */
            
            System.debug('>>>>' + response.getBody());
            if (response.getStatusCode() == 200) {
                Item lstData = (Item)JSON.deserialize(response.getBody(), Item.class);
                //SalesAIRecommendations.Item item = (SalesAIRecommendations.Item)JSON.deserialize(response.getBody(), SalesAIRecommendations.Item.class);
                System.debug('>>>>lstData'+lstData);

            if(lstData != null && lstData.data != null ){
                    //Map<Id, Recommendation__c> accRecommMap = new Map<Id, Recommendation__c>();
                    //Map<Id, Recommendation_Rationale__c> RecomRatnlMap = new Map<Id, Recommendation_Rationale__c>();
                    //Map<Id, Cheatsheet__c> cheatShtMap = new Map<Id, Cheatsheet__c>();

                    
                    Data freshData = lstData.Data;
                        System.debug('Accid>>>>' + accId);
                        recomnd = new Recommendation__c(Opportunity_Score__c = freshData.opportunityScore,
                                                                        Product_Service__c = freshData.productServiceRecommendation,
                                                                        Est_Value__c = freshData.contactYTDSales,
                                                                        Account__c = accId );
                        
                       // accRecommMap.put(data.accountNumber, recomnd);
                        
                        
                        //Recommendation Rationale Upsert
                        recomRational = new Recommendation_Rationale__c();                      
                        recomRational.Rationale1__c = freshData.productServiceRationale1;
                        recomRational.Rationale2__c = freshData.productServiceRationale2;
                        recomRational.Rationale3__c = freshData.productServiceRationale3;
                        recomRational.Rationale4__c = freshData.productServiceRationale4;
                        recomRational.Rationale5__c = freshData.productServiceRationale5;
                        recomRational.Rationale6__c = freshData.productServiceRationale6;
                        
                        //RecomRatnlMap.put(data.accountNumber, recomRational);
                        
                        //Cheatsheet upsert
                        cheatsht = new Cheatsheet__c();
                        cheatsht.Discount_Guidance__c = freshData.discountGuidance;
                        cheatsht.Pitch1__c = freshData.productCheatSheet1;
                        cheatsht.Pitch2__c = freshData.productCheatSheet2;
                        cheatsht.Pitch3__c = freshData.productCheatSheet3;
                        cheatsht.Pitch4__c = freshData.productCheatSheet4;
                        cheatsht.Pitch5__c = freshData.productCheatSheet5;
                        cheatsht.Pitch6__c = freshData.productCheatSheet6;
                        cheatsht.RelatedProducts1__c = freshData.relatedProduct1;
                        cheatsht.RelatedProducts2__c = freshData.relatedProduct2;
                        cheatsht.RelatedProducts3__c = freshData.relatedProduct3;
                        cheatsht.RelatedProducts4__c = freshData.relatedProduct4;
                        cheatsht.RelatedProducts5__c = freshData.relatedProduct5;
                        cheatsht.RelatedProducts6__c = freshData.relatedProduct6;
                       
                        //cheatShtMap.put(data.accountNumber, cheatsht);
                        }

                    upsert recomnd;
                    system.debug('recomnd >> '+recomnd.Id);
                    recomRational.Recommendation__c = recomnd.Id;
                    upsert recomRational;
                    cheatsht.Recommendation__c= recomnd.Id;
                    upsert cheatsht;
                        
               }
            }

        }

   global void finish(Database.BatchableContext BC){}
   
   global void execute(SchedulableContext sc){
      database.executebatch(new SalesAIChildDataSyncBatch());
   }
}
RajanRajan
Is their anyone active for help?