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
kevin05kevin05 

Attach second PDF if parameter is met on updated custom object record.

I have a class which looks for if there is a PDF already attached to a custom object record as well as a date field being less than TODAY. How do I have this class attach an additional file if another parameter is met? For instance if there is already a PDF attached to the record called "Letter.pdf." I would like an additional letter to be attached because the record has been edited to SecondLetter__c = TRUE. Thanks for your help.

 

global class pdfBatch implements Database.Batchable<sObject> {
    
    String query;
    String filename = 'Letter.pdf';
    
    global pdfBatch() {
        query = 'SELECT Id FROM Application__c ';
        query += 'WHERE Publish_Date_Time__c < TODAY';
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Application__c> scope) {
        String[] appIDs = new LIST<String>();
        for(Application__c app : scope){
            appIDs.add(app.id);
        }
        SET<String> appIDsWithPDFs = new SET<String>();
        for(Attachment atchmnt : [
            SELECT ParentId 
            FROM Attachment 
            WHERE name =:filename
            AND ParentId IN :appIDs
            LIMIT 5000
        ]){
            appIDsWithPDFs.add(atchmnt.ParentId);
        }
        Attachment[] attachments = new LIST<Attachment>();
        for(Application__c app : scope)
        {
            if(appIDsWithPDFs.contains(app.id)) continue;
            PageReference pdf = Page.Letter_PDFer;
            // add parent id to the parameters for standardcontroller
            pdf.getParameters().put('id',app.id);

            // the contents of the attachment from the pdf
            Blob body;

            try {

            // returns the output of the page as a PDF
            body = pdf.getContent();

            // need to pass unit test -- current bug  
            } catch (VisualforceException e) {
            body = Blob.valueOf('An error occurred.');
            }

            Attachment attachment = new Attachment();
            attachment.Body = body;
            attachment.Name = String.valueOf(filename);
            attachment.ParentId = app.id;
            attachments.add(attachment);
        }
        if (attachments.size()>0)
            insert attachments;     
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
    
}

Mario PariseMario Parise
Assumptions:

1) Application__c is your custom object.
2) SecondLetter__c is a field on Application__c.

A few thoughts:

1) You could set a boolean (possibly SecondLetter__c but the naming convention would be awkward... I'd recomment HasLetter__c) as TRUE the moment you do the first attachment. Then, add HasLetter__c to your query. If true, change your filename to "Letter2.pdf", and proceed.

2) You could instead create a LetterCount__c field (rather than a boolean) on the Application__c object. Query for it, increment it, then change your filename to something like:
filename = 'Letter' + app.LetterCount__c + '.pdf';
This has the benefit it allowing the same code to work no matter how many letters get attached. Should requirements every increase to support 3 or 4 or 500 (and requirements are ALWAYS increasing... you know the drill...) your code will already be prepared for it.
Raj VakatiRaj Vakati
Try this 
 
global class pdfBatch implements Database.Batchable<sObject> {
    
    String query;
    String filename = 'Letter.pdf';
    
    global pdfBatch() {
        query = 'SELECT Id FROM Application__c ';
        query += 'WHERE Publish_Date_Time__c < TODAY';
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Application__c> scope) {
        String[] appIDs = new LIST<String>();
        for(Application__c app : scope){
            appIDs.add(app.id);
        }
        SET<String> appIDsWithPDFs = new SET<String>();
        for(Attachment atchmnt : [
            SELECT ParentId 
            FROM Attachment 
            WHERE name =:filename
            AND ParentId IN :appIDs
            LIMIT 5000
        ]){
            appIDsWithPDFs.add(atchmnt.ParentId);
        }
        Attachment[] attachments = new LIST<Attachment>();
		Integer i =0 ; 
        for(Application__c app : scope)
        {
            if(appIDsWithPDFs.contains(app.id)) continue;
            PageReference pdf = Page.Letter_PDFer;
            // add parent id to the parameters for standardcontroller
            pdf.getParameters().put('id',app.id);

            // the contents of the attachment from the pdf
            Blob body;

            try {

            // returns the output of the page as a PDF
            body = pdf.getContent();

            // need to pass unit test -- current bug  
            } catch (VisualforceException e) {
            body = Blob.valueOf('An error occurred.');
            }

            Attachment attachment = new Attachment();
            attachment.Body = body;
            attachment.Name = 'Letter'+i+'.pdf';
            attachment.ParentId = app.id;
            attachments.add(attachment);
			i++;
        }
        if (attachments.size()>0)
            insert attachments;     
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
    
}

 
Mario PariseMario Parise
Hey Raj

Unless I'm missing something, I believe that will only increment i for each attachment in this particular loop. It won't check for existing attachments and increment from there, which I believe is one of the requirements.

However, you could probably slightly revise it as follows:
global class pdfBatch implements Database.Batchable<sObject> {
    
    String query;
    String filename = 'Letter.pdf';
    
    global pdfBatch() {
        query = 'SELECT Id FROM Application__c ';
        query += 'WHERE Publish_Date_Time__c < TODAY';
    }
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator(query);
    }

    global void execute(Database.BatchableContext BC, List<Application__c> scope) {
        String[] appIDs = new LIST<String>();
        for(Application__c app : scope){
            appIDs.add(app.id);
        }
        SET<String> appIDsWithPDFs = new SET<String>();
        for(Attachment atchmnt : [
            SELECT ParentId 
            FROM Attachment 
            WHERE name =:filename
            AND ParentId IN :appIDs
            LIMIT 5000
        ]){
            appIDsWithPDFs.add(atchmnt.ParentId);
        }
        Attachment[] attachments = new LIST<Attachment>(); 
        for(Application__c app : scope)
        {
            if(appIDsWithPDFs.contains(app.id)) continue;

            // The next few lines attempt to count the attachments on this Application.
            Integer i = 0;
            for (Attachment a : attachments) {
                if (a.ParentId == app.id) {
                    i++;
                }
            }
            
            PageReference pdf = Page.Letter_PDFer;
            // add parent id to the parameters for standardcontroller
            pdf.getParameters().put('id',app.id);

            // the contents of the attachment from the pdf
            Blob body;

            try {
                // returns the output of the page as a PDF
                body = pdf.getContent();

                // need to pass unit test -- current bug  
            } catch (VisualforceException e) {
                body = Blob.valueOf('An error occurred.');
            }

            Attachment attachment = new Attachment();
            attachment.Body = body;
            attachment.Name = 'Letter'+i+'.pdf';
            attachment.ParentId = app.id;
            attachments.add(attachment);
            i++;
        }
        if (attachments.size()>0)
            insert attachments;     
    }
    
    global void finish(Database.BatchableContext BC) {
        
    }
    
}