-3

We've 2 custom objects Discount Approval Process and Approval Request Notification We've started getting following error after sf Admin for Sales Team introduced a new field and made it required when creating a new record Discount Approval Process custom object.

Name of the field is Estimated_Total_Order_Netprice__c ( API Name), and it is a currency field. This field has been introduced recently(Required field) and was not part of Apex class OR test class when the code was deployed.

Below is the error message:

System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Estimated_Total_Order_Netprice__c]: [Estimated_Total_Order_Netprice__c] Stack Trace: Class.ApprovalRequestNotificationBatchTest: line 32, column 1

Apex Class and test Class are listed below. What I'm not sure is where exactly do I need to add this field in a test class so that test class will no longer be an issue.

Apex Class:

public without sharing class ApprovalRequestNotificationBatch
    implements Database.Batchable <sObject>,  Schedulable
{
    //  private properties declared in alphabetical order
    private Id administratorProfileId
    {
        get
        {
            return [ select id from profile
                      where name = 'System Administrator'
                      limit 1
                   ].Id;

        }

    }   //  administratorProfileId

    private Id orgWideEmailAddressId
    {
        get
        {        
            return [ select id from orgwideemailaddress
                      where displayname = 'Ag Discount Approvals'
                   ].Id;

        }

    }   //  orgWideEmailAddressId

    private String query = 'select actorid'
                         +       ', id'
                         +       ', processinstanceid'
                         +       ', processinstance.targetobjectid'            
                         +   ' from processinstanceworkitem'
                         +  ' where processinstanceid in '
                         + getProcessInstanceIds();

    private Id templateId    
    {
        get
        {
            if ( templateId == null )
                return TemplateSettings__c.getInstance (administratorProfileId).ApprovalRequestTemplateId__c;


            else
                return templateId;

        }

    }   //  templateId

    //  public methods listed in alphabetical order
    public ApprovalRequestNotificationBatch ()
    {

    }   //  constructor

    public Database.Querylocator start ( Database.BatchableContext BC )
    {
        //  variables declared in alphabetical order
        Database.Querylocator queryLocator = null;

        if ( query != null )
        {
            System.debug('batch query:  ' + query);

            queryLocator = Database.getQueryLocator(query);

        }   //  selection query is not null

        return queryLocator;

    }   //  start ()

    public void execute ( Database.BatchableContext BC , List <sObject> scope )
    {
        //  variables declared in alpohabetical order
        List <ProcessInstanceWorkItem>              instanceItems    = (List <ProcessInstanceWorkItem>) scope;
        Set  <Id>                                   itemIdSet        = new Set  <Id> ();
        Map  <Id, Approval_Request_Notification__c> itemToRequestMap = new Map  <Id, Approval_Request_Notification__c> (); 
        Approval_Request_Notification__c            newRequest       = null;
        List <Approval_Request_Notification__c>     newRequests      = null;
        Approval_Request_Notification__c            request          = null;
        List <Approval_Request_Notification__c>     requests         = new List <Approval_Request_Notification__c> ();
        Set  <Approval_Request_Notification__c>     requestSet       = new Set  <Approval_Request_Notification__c> ();
        List <Messaging.SendEmailResult>            results          = null;
        Discount_Approval_Process__c                testDiscountReq  = null;

        for ( ProcessInstanceWorkItem instanceItem : instanceItems )
            itemIdSet.add (instanceItem.Id);

        if ( System.Test.isRunningTest () )
        {
            requests = [ select discount_request__c
                              , id
                              , processing_status__c
                              , recipient__c
                              , workitem__c
                           from approval_request_notification__c
                          where workitem__c = 'ABCDEFG'
                       ];

        }

        else
        {
            requests = [ select discount_request__c
                              , id
                              , processing_status__c
                              , recipient__c
                              , workitem__c
                           from approval_request_notification__c
                          where workitem__c in : itemIdSet
                       ];

            for ( Approval_Request_Notification__c req : requests )
                itemToRequestMap.put (req.workitem__c, req);

            requests = new List <Approval_Request_Notification__c> ();

            for ( ProcessInstanceWorkItem instanceItem : instanceItems )
            {
                newRequests = new List <Approval_Request_Notification__c> ();

                if ( itemToRequestMap.containsKey (instanceItem.Id) )
                {
                    request = itemToRequestMap.get (instanceItem.Id);

                    if ( request.Processing_Status__c == 'Not Started' )
                        requests.add (request);         

                }

                else
                {
                    newRequest = new Approval_Request_Notification__c
                    (
                        Discount_Request__c = instanceItem.ProcessInstance.TargetObjectId
                    ,   Recipient__c        = instanceItem.ActorId
                    ,   WorkItem__c         = instanceItem.Id

                    );

                    newRequests.add (newRequest);

                }   //  work item already has a related notification request

                if ( ! newRequests.isEmpty () )
                {
                    insert newRequests;

                    requests.addAll (newRequests);

                }   //  there are new notification requests to insert

            }   //  each step in scope

        }   //  batch invoked during execution of a test method

        if ( ! requests.isEmpty () )
            sendNotificationsWithRequestAttachments (requests);

    }   //  execute batch job 

    public void execute ( SchedulableContext sc )
    {
        //  variables declared in alpohabetical order
        ApprovalRequestNotificationBatch batch     = new ApprovalRequestNotificationBatch ();
        Id                               processId = Database.executeBatch (batch, 10);

    }   //  execute scheuled job

    public void finish ( Database.BatchableContext BC )
    {
        //  variables declared in alphabetical order
        AsyncApexJob                        job        = null;
        Messaging.SingleEmailMessage        message    = new Messaging.SingleEmailMessage ();
        List <Messaging.SingleEmailMessage> messages   = new List <Messaging.SingleEmailMessage> ();
        List <String>                       recipients = new List <String> ();

        job = [ select createdby.email
                     , id
                     , jobitemsprocessed
                     , numberoferrors
                     , status
                     , totaljobitems
                  from asyncapexjob 
                 where id = : BC.getJobId ()
              ];

        recipients.add (job.CreatedBy.Email);

        message.setPlainTextBody ( 'The batch Apex job processed ' + job.TotalJobItems
                                 + ' batches with ' + job.NumberOfErrors + ' failures and executed'
                                 + ' the following query:  ' + query);
        message.setSubject       ( 'Approval Request Notification Batch '
                                 + 'completed with a status of '
                                 + job.Status + '.');
        message.setToAddresses (recipients);

        messages.add (message);

        Messaging.sendEmail (messages);

    }   //  finish ()

    //  private methods listed in alphabetical order
    private Set <Id> getProcessIdSet ()
    {
        //  variables declared in alphabetical order
        List <ProcessDefinition> processes        = new List <ProcessDefinition> ();
        Set <Id>                 processIdSet     = new Set <Id> ();
        String                   processIdSetting = TemplateSettings__c.getInstance (administratorProfileId).ProcessesToMonitor__c;
        Set <String>             processSet       = new Set <String> ();

        System.debug('processIdSetting: ' + processIdSetting);

        for ( String process : processIdSetting.split (';') )
            processSet.add (process);

        System.debug (Logginglevel.INFO, 'processSet:  ' + processSet);

        processes = [ select id from processdefinition
                       where developername in : processSet
                    ];

        for ( ProcessDefinition process : processes )
            processIdSet.add (process.Id);

        System.debug (Logginglevel.INFO, 'processIdSet:  ' + processIdSet);

        return processIdSet;

    }   //  getProcessIdSet ()

    //  private methods listed in alphabetical order
    private List <String> getProcessInstanceIds ()
    {
        //  variables declared in alphabetical order
        List <String>          instanceIds   = new List <String> ();
        Set  <String>          instanceIdSet = new Set  <String> ();
        List <ProcessInstance> instances     = new List <ProcessInstance> ();
        Set  <Id>              processIdSet  = getProcessIdSet ();

        instances = [    select id 
                              , targetobjectid
                           from processinstance
                          where processdefinitionid in : processIdSet
                            and status = 'Pending'
                       order by createddate desc
                    ];

        System.debug (Logginglevel.INFO, 'instances:  ' + instances);

        Integer maxLen = 10;
        if(instances.size() < 10)
            maxLen = instances.size();

        for ( Integer index = 0 ; index < maxLen ; index ++ )
            instanceIdSet.add (String.valueOf (instances [index].Id));

        System.debug (Logginglevel.INFO, 'instanceIdSet:  ' + instanceIdSet);

        for ( String instanceId : instanceIdSet )
            instanceIds.add ('\'' + instanceId + '\'');

        return instanceIds;

    }   //  getProcessInstanceIds ()

    private List <Attachment> getRequestAttachments
    ( Id requestId )
    {
        //  variables declared in alphabetical order
        String            query              = null;
        List <Attachment> requestAttachments = new List <Attachment> ();

        query = '  select body'
              +        ', contenttype'
              +        ', description'
              +        ', id'
              +        ', name'
              +    ' from attachment'
              +   ' where parentid = \'' + requestId + '\'';

        System.debug (Logginglevel.INFO, 'attachments query:  ' + query);

        requestAttachments = Database.query (query);

        return requestAttachments;

    }   //  getRequestAttachments ()

    private void sendNotificationsWithRequestAttachments
    ( List <Approval_Request_Notification__c> requests )
    {
        //  variables declared in alphabetical order
        Messaging.EmailFileAttachment        attachment         = null;
        List <Messaging.EmailFileAttachment> attachments        = null; 
        Messaging.SingleEmailMessage         message            = null; 
        List <Messaging.SingleEmailMessage>  messages           = null;
        List <Attachment>                    requestAttachments = null;
        List <Messaging.SendEmailResult>     results            = null;  

        for ( Approval_Request_Notification__c request : requests )
            request.Processing_Status__c = 'In Progress';

        update requests;

        for ( Approval_Request_Notification__c request : requests )
        {
            attachments        = new List <Messaging.EmailFileAttachment> (); 
            message            = new Messaging.SingleEmailMessage (); 
            requestAttachments = getRequestAttachments (request.Discount_Request__c);

            System.debug (Logginglevel.INFO, 'requestAttachments:  ' + requestAttachments);

            for ( Attachment requestAttachment : requestAttachments )
            {
                attachment = new Messaging.EmailFileAttachment ();

                attachment.setBody     (requestAttachment.Body);
                attachment.setFileName (requestAttachment.Name);             

                attachments.add (attachment);

            }   //  each attachment in list

            message.setBccSender             (false);
            message.setFileAttachments       (attachments);
            message.setOrgWideEmailAddressId (orgWideEmailAddressId);
            message.setSaveAsActivity        (false);
            message.setTargetObjectId        (request.Recipient__c);
            message.setTemplateId            (templateId);
            message.setWhatId                (request.Discount_Request__c);
            message.setUseSignature          (false);

            messages = new List <Messaging.SingleEmailMessage> ();

            messages.add (message);

            results = Messaging.sendEmail(messages);

            if ( results [0].isSuccess () )
                request.Processing_Status__c = 'Completed';

            else
            {
                request.Processing_Status__c = 'Failed';
                request.Error_Log__c         = results [0].getErrors () [0].getMessage ();

            }   //  message sent successfully

        }   //  each notification request in list

        update requests;

    }   //  sendNotificationWithRequestAttachments ()

Test Class:

@isTest(SeeallData=true)
private class ApprovalRequestNotificationBatchTest
{
    //  static constants declared in alphabetical order
    private static final String PROCESS_NAME = 'Test Process';

    //  static variables declared in alphabetical order
    private static Approval.ProcessSubmitRequest           approvalRequest     = null;
    private static Approval.ProcessResult                  approvalResult      = null;
    private static Attachment                              attachment          = null;
    private static ApprovalRequestNotificationBatch        batch               = null;
    private static String                                  cronId              = null;
    private static CronTrigger                             cronTrigger         = null;
    private static Discount_Approval_Process__c            discountRequest     = null;
    private static Approval_Request_Notification__c        notificationRequest = null;
    private static List <Approval_Request_Notification__c> requests            = null;
    private static TemplateSettings__c                     templateSettings    = null;

    static
    {
        discountRequest = TestingUtility.instantiateDiscountRequest ();

        insert discountRequest;

        System.assertEquals (1, [ select count()
                                    from discount_approval_process__c
                                   where id = : discountRequest.Id
                                ]
                            );

        attachment = TestingUtility.instantiateAttachment (discountRequest.Id);

        insert attachment;

        TestingUtility.createNotificationRequest ( discountRequest.Id
                                                 , UserInfo.getUserId ()
                                                 , 'ABCDEFG'
                                                 );

    }   //  code block common to all test methods

    private static testMethod void testNotificationBatch ()
    {
        TemplateSettings__c templSett = new TemplateSettings__c();
        templSett.ApprovalRequestTemplateId__c = '00XS0000000Mjcy';
        templSett.Letterhead_Url__c = 'https://cs1.salesforce.com/servlet/servlet.ImageServer?id=015S0000000gHDv';
        templSett.ProcessesToMonitor__c = 'Discount_Promo_TNL_CNH_EMEA;Discount_One_Time_TNL_LA;Tricia_s_Test_Approval_Process';
        templSett.ReplyToEmailAddress__c = 'discountapprovalresponse@x-32qfl8h6p5c04401tvrl9xdez7243sruxu96zohvdm5ueqig8a.s-3kszjma0.cs1.apex.sandbox.salesforce.com';
        templSett.Wizard_Url__c = 'https://cs1.salesforce.com/p/process/ProcessInstanceWorkitemWizardStageManager?id=';

        //insert templSett;

       // Insert an account
       /*Account a = new Account(Name='Test',annualRevenue=100.0);
        insert a;

        User user1 = [SELECT Id, isActive FROM User where isActive = true Limit 1];

        //Create an approval request for the account
        Approval.ProcessSubmitRequest req1 = 
            new Approval.ProcessSubmitRequest();
        req1.setObjectId(a.id);

        // Submit on behalf of a specific submitter
        req1.setSubmitterId(user1.Id);

        // Submit the approval request for the account
        Approval.ProcessResult result = Approval.process(req1);*/

        System.Test.startTest ();



        try{
            templateSettings = [ select approvalrequesttemplateid__c
                                  , letterhead_url__c
                                  , processestomonitor__c
                                  , replytoemailaddress__c
                                  , wizard_url__c
                               from templatesettings__c
                           ];
            //System.assertEquals('Discount_Promo_TNL_CNH_EMEA;Discount_One_Time_TNL_LA;Tricia_s_Test_Approval_Process', templateSettings.ProcessesToMonitor__c);
        } catch(Exception e) {
            System.debug('The following exception has occurred: ' + e.getMessage());
            templateSettings = null;
            System.assertEquals(null, templateSettings);
        }

          batch  = new ApprovalRequestNotificationBatch();
          cronId = System.scheduleBatch (batch, 'Test Batch', 1);

        System.Test.stopTest ();

        cronTrigger = [ select id
                             , nextfiretime
                             , timestriggered
                          from crontrigger
                         where id = : cronId
                      ];

        System.assertEquals (0, cronTrigger.TimesTriggered);

    }   //  testNotificationBatch ()

closed as off-topic by battery.cord, glls, Sebastian Kessel, Martin Lezer, Raul Oct 31 '17 at 10:54

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions on problems in code you've written must describe the specific problem and include valid code to reproduce it. For help writing short, self-contained syntactically-valid examples, see: SSCCE.org" – battery.cord, glls, Sebastian Kessel, Martin Lezer, Raul
If this question can be reworded to fit the rules in the help center, please edit the question.

  • 2
    Please include the error as text, not image. Also, the error message seems like it could hardly be more clear. You need to specify a value for the indicated field. – Adrian Larson Oct 30 '17 at 18:41
  • Thanks, Adrian. name of the field is Estimated_Total_Order_Netprice__c ( API Name), and it is a currency field. This field has been introduced recently(Required field) and was not part of Apex class OR test class when the code was deployed. Below is the error message: System.DmlException: Insert failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Required fields are missing: [Estimated_Total_Order_Netprice__c]: [Estimated_Total_Order_Netprice__c] Stack Trace: Class.ApprovalRequestNotificationBatchTest: line 32, column 1 – sfdcDev Oct 30 '17 at 18:48
  • Please edit your post with any clarifications. You need to update your test class to add that field. – Adrian Larson Oct 30 '17 at 18:50
  • 1
    The stack trace tells you exactly which line is throwing the error. What DML Statement do you perform on line 32? – Adrian Larson Oct 30 '17 at 19:05
  • 1
    I've voted to close this question, as it does not contain the relevant code needed to assist you. – battery.cord Oct 30 '17 at 19:49
0

You have TestingUtility class and a method instantiateDiscountRequest in it. I believe which creates test Discount_Approval_Process__c records. Adding Estimated_Total_Order_Netprice__c and its value in instantiateDiscountRequest may resolve your problem.

Not the answer you're looking for? Browse other questions tagged or ask your own question.