Salesforce.com:System.NullPointerException:尝试取消引用null对象

时间:2013-01-09 23:16:36

标签: salesforce

我在尝试测试我的Apex测试类时遇到以下错误

消息: System.NullPointerException:尝试取消引用空对象

堆栈跟踪错误: Class.RenewalNotificationController.mergeExistingFields:第321行,第1列Class.RenewalNotificationController.mergeAndCreateMail:第227行,第1列Class.RenewalNotificationController.sendMail:第177行,第1列Class.RenewalNotificationControllerTEST.testRenewalNotifications:第71行,第1列

以下是Apex测试类

我很快就会添加我的Apex课程。

非常感谢任何帮助!

干杯! 隆美尔

Apex测试类

public class RenewalNotificationControllerTEST {

public testMethod static void testRenewalNotifications() {

//==============30 Day Test================
Opportunity opp1 = new Opportunity(Name = 'Test1', Renewal_Notice_Email__c = 'rmehta@apprivo.com', 
Probability = 5, Description = 'test', CloseDate = Date.today() + 5,Contract_Expires__c = Date.today() + 5, Sales_Engagement_Strategy__c = 'not null',
Amount = 1000, StageName = 'Awareness', Theater__c='NA');
insert opp1;

Renewal__c renewal1 = new Renewal__c(Renewal_Opportunity__c = opp1.Id, 
Serviced_Product_SKU__c = 'test SKU', Parent_Serial_Number__c = '123456', 
Serial_Number__c = 'SN123', Line_End_Date__c = Date.today() + 10);
insert renewal1;

//==============60 Day Test================
Opportunity opp2 = new Opportunity(Name = 'Test2', Renewal_Notice_Email__c = 'rmehta@apprivo.com', 
Probability = 5, Description = 'test', CloseDate = Date.today() + 65,Contract_Expires__c = Date.today() + 65, Sales_Engagement_Strategy__c = 'not null',
Amount = 1000, StageName = 'Awareness', Theater__c='NA');
insert opp2;

Renewal__c renewal2 = new Renewal__c(Renewal_Opportunity__c = opp2.Id, 
Serviced_Product_SKU__c = 'test SKU', Parent_Serial_Number__c = '123456', 
Serial_Number__c = 'SN123', Line_End_Date__c = Date.today() + 20);
insert renewal2;

//==============90 Day Test================
Opportunity opp3 = new Opportunity(Name = 'Test3', Renewal_Notice_Email__c = 'rmehta@apprivo.com', 
Probability = 50, Description = 'test', CloseDate = Date.today() + 95, Contract_Expires__c = Date.today() + 95, Sales_Engagement_Strategy__c = 'not null',
Amount = 1000, StageName = 'Awareness', Theater__c='NA');
insert opp3;

Renewal__c renewal3 = new Renewal__c(Renewal_Opportunity__c = opp3.Id, 
Serviced_Product_SKU__c = 'test SKU', Parent_Serial_Number__c = '123456', 
Serial_Number__c = 'SN123', Line_End_Date__c = Date.today() + 10);
insert renewal3;

//==============-1 Day Test================
Opportunity opp4 = new Opportunity(Name = 'Test1', Renewal_Notice_Email__c = 'rmehta@apprivo.com', 
Probability = 5, Description = 'test', CloseDate = Date.today() - 5,Contract_Expires__c = Date.today() - 5, Sales_Engagement_Strategy__c = 'not null',
Amount = 1000, StageName = 'Awareness', Theater__c='NA');
insert opp4;

BrandTemplate bt = [Select Id from BrandTemplate Limit 1];
/* EmailTemplate template = new EmailTemplate(Name = 'testTemplate', 
FolderId = RenewalNotificationController.FOLDER_ID,
Subject = 'Test Subject {!Opportunity.CloseDate}',
Body = 'Test Body {!Opportunity.Name} <Renewals> \n {!Opportunity.Theater__c} ' +
'\n {!Opportunity.CloseDate} \nfrom a F5 rep', 
HtmlValue = 'Test Body {!Opportunity.Name} <Renewals> <br> {!Opportunity.Theater__c} ' +
'<br> {!Opportunity.CloseDate} <br>from a F5 rep',
TemplateType= 'HTML',
BrandTemplateId = bt.Id, TemplateStyle = 'freeForm');
insert template;*/
EmailTemplate template = [Select Id, Name, Subject, Body, HtmlValue from EmailTemplate where FolderId = :RenewalNotificationController.FOLDER_ID Limit 1];

Test.startTest();
RenewalNotificationController controller = new RenewalNotificationController();

List<SelectOption> options = controller.getFilterOptionItems();

controller.FilterOption = '30';
controller.createTaskSubject();
controller.onDateFilterChange();
List<RenewalNotificationController.OppWrapper> opportunities = controller.getRenewalOpportunities();
for (RenewalNotificationController.OppWrapper wrapper : opportunities) {
wrapper.setSelected(true);
} 
controller.SelectedTemplate = template.Id;
controller.onEmailTemplateChange();
controller.sendMail();

controller.FilterOption = '60';
controller.createTaskSubject();
controller.onDateFilterChange();
controller.sendMail();

controller.FilterOption = '90';
controller.createTaskSubject();
controller.onDateFilterChange(); 
controller.sendMail();

controller.FilterOption = '-1';
controller.createTaskSubject();
controller.onDateFilterChange();

controller.FilterOption = '-14';
controller.createTaskSubject();
controller.onDateFilterChange();

controller.FilterOption = '-30';
controller.createTaskSubject();
controller.onDateFilterChange();

controller.FilterOption = '-90';
controller.createTaskSubject();
controller.onDateFilterChange();

controller.getSuccessEmails();
controller.getFailureEmails();

controller.backToRenewals();

Test.stopTest();
}
}

Apex Class

public class RenewalNotificationController {

    public String filterOption {get; set;}
    List<OppWrapper> wrapperList;
    public String NoOpportunityMessage {get; set;}
    public String selectedTemplate {get; set;}

    private String STAGE_NAME = 'Internal Education';
    private Integer PROBABILITY = 25;
    public static final String FOLDER_ID = '00l50000000vdRRAAY';

    //used on page2
    List<Opportunity> successEmails;
    List<Opportunity> failureEmails;

    private static final String REGEX = '\\{![a-zA-Z\\._]*\\}';

    private Map<String, String> opportunityFields;

    public RenewalNotificationController(){
     filterOption = 'none';


        opportunityFields = new Map<String, String>();
        opportunityFields.put('{!Opportunity.Account}', 'Account.Name');
        opportunityFields.put('{!Opportunity.CloseDate}', 'CloseDate');
        opportunityFields.put('{!Opportunity.Amount}', 'Amount');
        opportunityFields.put('{!Opportunity.Description}', 'Description');
        opportunityFields.put('{!Opportunity.Name}', 'Name');
        opportunityFields.put('{!Opportunity.Probability}', 'Probability');
        opportunityFields.put('{!Opportunity.Contract_Expires__c}', 'Contract_Expires__c');
        opportunityFields.put('{!Opportunity.OwnerEmail}', 'Owner.Email');
        opportunityFields.put('{!Opportunity.OwnerFullName}', 'Owner.Name');
        opportunityFields.put('{!Opportunity.OwnerFirstName}', 'Owner.FirstName');
        opportunityFields.put('{!Opportunity.OwnerLastName}', 'Owner.LastName');
        opportunityFields.put('{!Opportunity.OwnerPhone}', 'Owner.Phone');
        opportunityFields.put('{!Opportunity.OwnerTitle}', 'Owner.Title');

        onDateFilterChange();
    }


    public List<OppWrapper> getRenewalOpportunities() {
        return wrapperList;
    }

    public void onEmailTemplateChange() {
        System.debug('onEmailTemplateChange()');
        //List<SelectOption> options = getEmailTemplates();
        for (OppWrapper wrapper : wrapperList) {
            //Boolean selected = wrapper.getSelected();
            //unccoment thhis if only the selecyted ones should change
            //if (selected) {
                //String template = (selectedTemplate == null) ? options.get(0).getValue() : selectedTemplate;
                wrapper.setEmailTemplate(selectedTemplate);
            //}
        }
    }

    public void onDateFilterChange() {

        System.debug('selectedTemplate = ' + selectedTemplate);
        System.debug('f1 = ' + filterOption);

        if(filterOption != 'none'){
       String queryString = 'select Id, Renewal_Notice_Email__c, Probability, OwnerId, Owner.Email, Owner.FirstName, Owner.LastName, Owner.Name, Owner.Phone, Owner.Title, Name, LastActivityDate, Description, CloseDate, Contract_Expires__c, Amount, Account.Name, AccountId From Opportunity Where OwnerId = \'' + UserInfo.getUserID() + '\' AND Id IN (select Renewal_Opportunity__c from Renewal__c) AND Probability > 0 AND Probability < 100' ; 

       Date startDate;
       Date endDate;

       //Determine the end and start dates for the renewal query
   if(filterOption == '30'){
        queryString += 'AND (Contract_Expires__c = THIS_MONTH OR Contract_Expires__c = NEXT_MONTH)';
       }else if(filterOption == '60'){
        startDate = Date.newInstance(Date.today().year(),Date.today().Month() + 2,1);
        endDate = Date.newInstance(Date.today().year(),Date.today().Month() + 2,  Date.daysInMonth(startDate.year(),startDate.Month()));
        queryString += 'AND Contract_Expires__c >= :startDate AND Contract_Expires__c <= :endDate';
       }else if(filterOption == '90'){
        startDate = Date.newInstance(Date.today().year(),Date.today().Month() + 3,1);
        endDate = Date.newInstance(Date.today().year(),Date.today().Month() + 3,  Date.daysInMonth(startDate.year(),startDate.Month()));
        queryString += 'AND Contract_Expires__c >= :startDate AND Contract_Expires__c <= :endDate';
   }else if(filterOption == '-1'){
startDate = Date.today().addDays(-14);
        endDate = Date.today().addDays(-1);
        queryString += 'AND Contract_Expires__c > :startDate AND Contract_Expires__c <= :endDate';          
       }else if(filterOption == '-14'){
        startDate = Date.today().addDays(-30);
        endDate = Date.today().addDays(-14);
        queryString += 'AND Contract_Expires__c > :startDate AND Contract_Expires__c <= :endDate';
       }else if(filterOption == '-30'){
        startDate = Date.today().addDays(-89);
        endDate = Date.today().addDays(-30);
        queryString += 'AND Contract_Expires__c >= :startDate AND Contract_Expires__c <= :endDate';
       }else if(filterOption == '-90'){
        endDate = Date.today().addDays(-90);
        queryString += 'AND Contract_Expires__c <= :endDate';
       }      

       system.debug('q1 ' + queryString);
       List<Opportunity> opportunities = Database.query(queryString);

       System.debug('opportunities size=' + opportunities.size());
       //to set message if no opp are found
       noOpportunityMessage = '';
       if (opportunities.size() == 0) {
           noOpportunityMessage = 'No Opportunities found for the selected criteria.';
       }

       //create wrapper
       wrapperList = new List<OppWrapper>();
       List<SelectOption> options = getEmailTemplates();
       for (Opportunity opp : opportunities) {
           OppWrapper wrapper = new OppWrapper();
           wrapper.setOpportunity(opp);
           wrapper.setSelected(false);
           wrapperList.add(wrapper);
           String template = (selectedTemplate == null) ? options.get(0).getValue() : selectedTemplate;
           wrapper.setEmailTemplate(template);
       }
        }
    }

    public List<SelectOption> getFilterOptionItems() {
        List<SelectOption> options = new List<SelectOption>();
        options.add(new SelectOption('none','-None-'));
        options.add(new SelectOption('30','30 Day Notice'));
        options.add(new SelectOption('60','60 Day Notice'));
        options.add(new SelectOption('90','90 Day Notice'));
        options.add(new SelectOption('-1','1 Day Lapse Notice'));
        options.add(new SelectOption('-14','14 Day Lapsed Notice'));
        options.add(new SelectOption('-30','30 Day Lapsed Notice'));
        options.add(new SelectOption('-90','90 Day Lapsed Notice'));
        return options;
    }

    public List<SelectOption> getEmailTemplates() {
        List<EmailTemplate> templates = [Select e.Name, e.Id From EmailTemplate e where e.FolderId= :FOLDER_ID Order By e.Name];
        List<SelectOption> options = new List<SelectOption>();
        for(EmailTemplate t : templates) {
            options.add(new SelectOption(t.id,t.name));
        }

        return options;
    }

    /*
    * Action method called from the page
    */
    public PageReference sendMail() {
                //array for holding the mails
        Messaging.SingleEmailMessage[] mails = new List<Messaging.SingleEmailMessage>();

        //create a map so that we can avoid queries to get template details.
        Map<ID, TemplateDetails> emailTemplateMap = new Map<ID, TemplateDetails>();

        //get selected checkboxes
        for (OppWrapper wrapper : wrapperList) {
            Boolean selected = wrapper.getSelected();
            if (selected) {
                String emailTemplateId = wrapper.getEmailTemplate();
                System.debug('sendmail(): opp = ' + wrapper.getOpportunity().Name + ', Template ID = ' + emailTemplateId);
                //check if template exists in map
                TemplateDetails templateDetails = emailTemplateMap.get(emailTemplateId);
                if (templateDetails == null) {
                    //get the subject and body of the template
                    EmailTemplate emailTemplate = [Select e.Name, e.Subject, e.Id, e.HtmlValue, e.Body From EmailTemplate e Where e.Id= :emailTemplateId];
                    templateDetails = new TemplateDetails();
                    emailTemplateMap.put(emailTemplateId, templateDetails);
                    templateDetails.setEmailTemplate(emailTemplate);
                    //get documents for this email template and add it to template details
                    List<DocumentAttachmentMap> attachments = [Select d.DocumentId From DocumentAttachmentMap d 
                            Where d.ParentId = :emailTemplateId];
                    templateDetails.setDocumentIds(attachments);
                }

                //create the merged email and add it array
                Messaging.SingleEmailMessage mail = mergeAndCreateMail(templateDetails, wrapper.getOpportunity());
                mails.add(mail);

            }
        }
        if (mails.size() == 0) {
            return null;
        }
        System.debug('Now Sending email ');
        Messaging.SendEmailResult[] resultArr = Messaging.sendEmail(mails);
        System.debug('Send email result = ' + resultArr[0]);
        failureEmails = new List<Opportunity>();
        successEmails = new List<Opportunity>();
        Integer i = 0;
        for (OppWrapper wrapper : wrapperList) {
            Boolean selected = wrapper.getSelected();
            if (selected) {
                Messaging.SendEmailResult result = resultArr[i];
                if (result.isSuccess()) { //error
                    successEmails.add(wrapper.getOpportunity());    
                } else {
                    failureEmails.add(wrapper.getOpportunity());
                } 
                i++;
            }

        }       
        //90 day notifications will update opportunity probability to 30% and stage to 'Internal Education'.
        //if (filterOption.equals('2')) {
            updateOpportunities();
        //}
        //create tasks for the emails sent
        createTask();
        return Page.renewalNotificationResult;
    }

    /*
     * Called from the result page to go back to the renewals
     */
    public PageReference backToRenewals() {
        return Page.renewalNotification;
    }

/*******************mail methods****************************/

    private Messaging.SingleEmailMessage mergeAndCreateMail(TemplateDetails templateDetails, Opportunity opp) {
        EmailTemplate emailTemplate = templateDetails.getEmailTemplate();

        //merge existing fields
        String subject = emailTemplate.Subject;
        subject = mergeExistingFields(subject, opp);

        String htmlBody = emailTemplate.HtmlValue;
        System.debug('htmlBody = ' + htmlBody);
        htmlBody = mergeExistingFields(htmlBody, opp);

        String textBody = emailTemplate.Body;
        textBody = mergeExistingFields(textBody, opp);

        //merge dynamic fields
        Set<String> mergeFieldSet = getMergeFieldSet(subject, htmlBody, textBody);

        //we have to make the merge fields on the object type. 
        Map<String, List<String>> mergeFieldMap = getMergeFieldMap(mergeFieldSet);
        System.debug('mergeFieldMap = ' + mergeFieldMap);

        //now for each key in the array we need to make a dynamic soql
        //example of mergeFieldMap = {Opportunity=(Business_Type__c, Theater__c)}
        for (String s : mergeFieldMap.keySet()) {
            List<String> columnsForSoql = mergeFieldMap.get(s);
            String sColumnsForSoql = getListAsString(columnsForSoql);
            SObject sObj = null;
            if (s.equalsIgnoreCase('opportunity')) {
                sObj = Database.query('Select ' + sColumnsForSoql + ' from opportunity where id = \'' + opp.id + '\'');
            } else if (s.equalsIgnoreCase('user')) {
                sObj = Database.query('Select ' + sColumnsForSoql + ' from user where id = \'' + UserInfo.getUserID() + '\'');
            }
            subject = mergeDynamicFields(subject, sObj, mergeFieldSet);
            htmlBody = mergeDynamicFields(htmlBody, sObj, mergeFieldSet);
            textBody = mergeDynamicFields(textBody, sObj, mergeFieldSet);
        }

        //now get the renewals
        List<Renewal__c> renewals = getRenewals(opp);
        if (htmlBody.indexOf('<Renewals>') != -1 || htmlBody.indexOf('&lt;Renewals&gt;') != -1) {
            String htmlRenewals = printHtmlRenewals(renewals);
            if (htmlBody.indexOf('<Renewals>') != -1) {
                Integer startIndex = htmlBody.indexOf('<Renewals>');
                htmlBody = htmlBody.substring(0, startIndex)  + htmlRenewals + htmlBody.substring(startIndex + 10); //10 is length of renewals
            }
            if (htmlBody.indexOf('&lt;Renewals&gt;') != -1) {
                Integer startIndex = htmlBody.indexOf('&lt;Renewals&gt;');
                htmlBody = htmlBody.substring(0, startIndex)  + htmlRenewals + htmlBody.substring(startIndex + 16); //10 is length of renewals
            }

        }

        if (textBody.indexOf('<Renewals>') != -1 || textBody.indexOf('&lt;Renewals&gt;') != -1) {
            String textRenewals = printTextRenewals(renewals);
            if (textBody.indexOf('<Renewals>') != -1) {
                Integer startIndex = textBody.indexOf('<Renewals>');
                textBody = textBody.substring(0, startIndex)  + textRenewals + textBody.substring(startIndex + 10); //10 is length of renewals
            }
            if (textBody.indexOf('&lt;Renewals&gt;') != -1) {
                Integer startIndex = textBody.indexOf('&lt;Renewals&gt;');
                textBody = textBody.substring(0, startIndex)  + textRenewals + textBody.substring(startIndex + 16); //16 is length of renewals
            }
        }

        //now set the mail object
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setSubject(subject);
        mail.setHtmlBody(htmlBody);
        mail.setPlainTextBody(textBody);
        String[] userEmail = new List<String>();
        userEmail.add(getUserEmail()); 
        mail.setBccAddresses(userEmail);
        //set the attachments
        ID[] documentIds = templateDetails.getDocumentIds();
        if (documentIds != null) {
            System.debug('documentIds = ' + documentIds[0]);
            mail.setDocumentAttachments(documentIds);
        }

        //get the to Addresses
        String renewalNoticeEmail = opp.Renewal_Notice_Email__c;
        System.debug('renewalNoticeEmail = ' + renewalNoticeEmail);
        String[] toAddresses = renewalNoticeEmail.split(';'); //there maybe multiple
        mail.setToAddresses( toAddresses );
        return mail;
    }
private String mergeExistingFields(String text, Opportunity opp) {
            Set<String> existingFields = opportunityFields.keySet();
            for (String mergeField : existingFields) {
                System.debug('mergeField = ' + mergeField);
                Integer index = text.indexOf(mergeField);
                while (index != -1) {
                    String fieldSoqlName = opportunityFields.get(mergeField);
                    String value = '';

                    if (fieldSoqlName.startsWith('Account')) {
                        Account a = opp.Account;
                        fieldSoqlName = fieldSoqlName.substring(8);
                        value = (String) a.get(fieldSoqlName);
                    } else if (fieldSoqlName.startsWith('Owner')) {
                        User u = opp.Owner;
                        fieldSoqlName = fieldSoqlName.substring(6);
                        value = (String) u.get(fieldSoqlName);                                  
                    } else {
                        Object obj = opp.get(fieldSoqlName);
                        if (obj instanceof Date) {
                            Date dt = Date.valueOf(obj);
                            if (dt != null)
                                value = dt.month() + '/' + dt.day() + '/' + dt.year();
                            else
                                value = '';

                        } else {                                        
                            value = String.valueOf(obj);
                        }
                    }
                    if (value == null) value = '';

                    System.debug(fieldSoqlName + ' = ' + value);
                    Boolean more = text.length() > index + mergeField.length();
                    text = text.substring(0, index) + value + ((more) ? text.substring(index + mergeField.length()) : '');
                    index = text.indexOf(mergeField);       
                }
            }
            return text;
        }

        /*
         * Merges the fields retrieved by the dynamic query.
         */
        private String mergeDynamicFields(String text, SObject sObj, Set<String> mergeFieldSet) {

            for (String mergeField : mergeFieldSet) {
                Integer index = text.indexOf(mergeField);
                while (index != -1) {
                    String fieldValue = '';
                    String mergeFieldColumn = getMergeFieldColumn(mergeField);
                    System.debug('mergeFieldColumn = ' + mergeFieldColumn);
                    if (sObj != null) {
                        Object obj = sObj.get(mergeFieldColumn);
                        if (obj instanceof Date) {
                            Date dt = Date.valueOf(obj);
                            if (dt != null)
                                fieldValue = dt.month() + '/' + dt.day() + '/' + dt.year();                                             
                        } else {  
                            if (obj != null)                                      
                                fieldValue = String.valueOf(obj);
                        }
                    }
                    System.debug('fieldValue = ' + fieldValue);
                    if (fieldValue == null) fieldValue = '';
                    Boolean more = text.length() > index + mergeField.length();
                    text = text.substring(0, index) + fieldValue + ((more) ? text.substring(index + mergeField.length()) : '');
                    index = text.indexOf(mergeField);       
                }
            }

            return text;
        }

    /*
     * adds the merge fields to the Set. Set ensures they are added only once
     */
        private void extractMergeFields(String str, Set<String> mergeFieldSet) {
            Pattern p = pattern.compile(REGEX);
            Matcher m = p.matcher(str); // get a matcher object
            while(m.find()) {
                System.debug('group(): ' + m.group(0));
                mergeFieldSet.add(m.group(0));
            }
        }


        //example - mergeFieldSet = {{!Opportunity.Business_Type__c}, {!Opportunity.Theater__c}}
        private Set<String> getMergeFieldSet(String subject, String htmlBody, String textBody) {
                Set<String> mergeFieldSet = new Set<String>();
                extractMergeFields(subject, mergeFieldSet);
                extractMergeFields(htmlBody, mergeFieldSet);
                extractMergeFields(textBody, mergeFieldSet);
                System.debug('mergeFieldSet = ' + mergeFieldSet); 
                return mergeFieldSet;
        }

    /*
    * takes the merge field set and creates a map
    * Map is like - Opportunity = List {Theater__c, SomeField}
    */
    private Map<String, List<String>> getMergeFieldMap(Set<String> mergeFieldSet) {
        Map<String, List<String>> mergeFieldMap = new Map<String, List<String>>();
        for (String mergeField : mergeFieldSet) {
                String mergeFieldObject = getMergeFieldObject(mergeField);
                String mergeFieldColumn = getMergeFieldColumn(mergeField);
                List<String> mergeFieldColumnList = mergeFieldMap.get(mergeFieldObject);
                if (mergeFieldColumnList == null) {
                        mergeFieldColumnList = new List<String>();
                        mergeFieldMap.put(mergeFieldObject, mergeFieldColumnList);      
                }
                mergeFieldColumnList.add(mergeFieldColumn);
        }
        return mergeFieldMap;
    }

    private String getMergeFieldObject(String mergeField) {
        Integer index = mergeField.indexOf('.');
        if (index != -1)
            return mergeField.substring(2, index);
        return  mergeField;
    }

    private String getMergeFieldColumn(String mergeField) {
        Integer index = mergeField.indexOf('.');
        if (index != -1)
            return mergeField.substring(index + 1, mergeField.length() -1);
        return  mergeField;
    }

    private void updateOpportunities() {
        List<Opportunity> opportunities = new List<Opportunity>();
        for (OppWrapper wrapper : wrapperList) {
            Boolean selected = wrapper.getSelected();
            if (selected) {
                Opportunity opp = wrapper.getOpportunity();
                Decimal prob = opp.Probability;
                if (prob == 5) {
                    opp.StageName = 'Research and Internal Education';
                    opp.Probability = PROBABILITY;
                    opportunities.add(opp);             
                }
            }
        }
        update opportunities;
    }

    private void createTask() {
        List<Task> taskList = new List<Task>();
        for (OppWrapper wrapper : wrapperList) {
            Boolean selected = wrapper.getSelected();
            if (selected) {
                Task t = new Task();
                t.WhatId = wrapper.getOpportunity().Id;
                t.ActivityDate = Date.today();
                t.Description = 'A renewal notice has been sent to the following recipient(s): ' + wrapper.getOpportunity().get('Renewal_Notice_Email__c');
                t.OwnerId = UserInfo.getUserID();
                t.Status = 'Completed';
                t.Subject = createTaskSubject();
                taskList.add(t);            
            }
        }
        if (taskList.size() > 0) {
            insert taskList;
        }
    }

    public String createTaskSubject() {
        String txt = '';
        if (filterOption.equals('30')) { //60 days
            txt = '30';
        }else if (filterOption.equals('60')) { //60 days
            txt = '60';
        }else if (filterOption.equals('90')) { //60 days
            txt = '90';
        }else if (filterOption.equals('-1')) { //60 days
            txt = '-1';
        }else if (filterOption.equals('-14')) {  //90 days
            txt = '-14';
        }else if (filterOption.equals('-30')) {  //90 days
            txt = '-30';
        }else if (filterOption.equals('-90')) {  //90 days
            txt = '-90';
        }
        return 'Email: F5 Maintenance ' + txt + ' Day Renewal Notice';
    }

private String getUserEmail() {
User activeUser = [Select Email From User where Username = :UserInfo.getUserName() limit 1];
return activeUser.Email;
}

/* *************************renewal methods ********************************* */        
    private List<Renewal__c> getRenewals(Opportunity opp) {
        String oppId = opp.Id;
        List<Renewal__c> renewals  = [Select r.Serviced_Product_SKU__c, r.Serial_Number__c, r.Parent_Serial_Number__c, r.Line_End_Date__c From Renewal__c r Where Renewal_Opportunity__c =:oppId  OR Merged_to_Opportunity__c = :oppId];
        return renewals;
    }

    private String printHtmlRenewals(List<Renewal__c> renewals) {
        String htmlRenewals = '<table>';
        for (Renewal__c r : renewals) {
            htmlRenewals += '<tr>';
            htmlRenewals += '<td align=\'left\' width=\'20%\'>' + r.Serviced_Product_SKU__c + '</td>';
                htmlRenewals += '<td align=\'left\' width=\'15%\'>' + r.Parent_Serial_Number__c + '</td>';
                htmlRenewals += '<td align=\'left\' width=\'15%\'>' + r.Serial_Number__c + '</td>';
                Date dt = r.Line_End_Date__c;
                htmlRenewals += '<td align=\'left\' width=\'20%\'>' + dt.month() + '/' + dt.day() + '/' + dt.year() + '</td>';
            htmlRenewals += '</tr>';
        }
        htmlRenewals += '</table>';
        return htmlRenewals;
    }

    private String printTextRenewals(List<Renewal__c> renewals) {
        String textRenewals = '\n';
        for (Renewal__c r : renewals) {
        textRenewals += r.Serviced_Product_SKU__c + '\t';
            textRenewals += r.Parent_Serial_Number__c + '\t';
            textRenewals += r.Serial_Number__c + '\t';
            textRenewals += Date.valueOf(r.Line_End_Date__c) + '\n';
        }
        textRenewals += '\n';
        return textRenewals;
    }


/* 
 *****************util method ********************************* 
 */

    private String getListAsString(List<String> columnsForSoql) {
        String retStr = '';
        for (String s : columnsForSoql) {
                if (retStr != '') retStr += ',';
                retStr += s;
        }
        System.debug('getListAsString(): retStr = ' + retStr);
        return retStr;
    }

/*
 *****************getters *********************************
 */

    public List<Opportunity> getSuccessEmails() {
        return successEmails;   
    }

    public List<Opportunity> getFailureEmails() {
        return failureEmails;   
    }

    /*
     *******************wrapper class **************
     */
    public class OppWrapper {

        private Opportunity opportunity;
        private String emailTemplate;
        private Boolean selected;

        public void setOpportunity(Opportunity opportunity) {
                this.opportunity = opportunity; 
        }

        public Opportunity getOpportunity() { return this.opportunity; }

        public void setEmailTemplate(String emailTemplate) {
                this.emailTemplate = emailTemplate;     
        }

        public String getEmailTemplate() { return this.emailTemplate; } 


        public void setSelected(Boolean selected) {
                this.selected = selected;     
        }

        public Boolean getSelected() { return this.selected; } 
    }

        /*
         *********holder class for template details ******************
         */
        private class TemplateDetails {

                private EmailTemplate emailTemplate;
                private ID[] documentIds;

                public void setEmailTemplate(EmailTemplate emailTemplate) { this.emailTemplate = emailTemplate; }

                public EmailTemplate getEmailTemplate() { return this.emailTemplate; }  

                public void setDocumentIds(List<DocumentAttachmentMap> attachments) { 
                        if (attachments != null && attachments.size() > 0) {
                                documentIds = new ID[attachments.size()];
                                for (Integer i = 0; i < attachments.size(); i++) {
                                        documentIds[i] = attachments.get(i).DocumentId;
                                }
                        }
                }

                public List<ID> getDocumentIds() { return this.documentIds; }     
        }     
}

1 个答案:

答案 0 :(得分:1)

堆栈跟踪告诉您问题所在:Class.RenewalNotificationController.mergeExistingFields: line 321, column 1

转到该行并查看代码。从那一点开始备份,看看你如何获得NULL值。查看调试日志以查看调用路径并观察传递给该函数的字段的值。如有必要,请添加其他System.Debug()语句。

您拥有解决问题所需的一切,如果没有Salesforce组织中的代码,您就无法做到这一点。

相关问题