0

I need to achieve multiple download on list view of Invoice object.

Requirement: Invoice Object has Notes and Attachments Related list. If Notes and Attachment is not null for Invoice Record then it should download the InvoicePDF(vfp) if attachment is null for Invoice Record then it should download InvoiceWithoutAttachmentPDF(vfp).

I tried something but I can achieve the correct download on single selection of Record on List view. If i try to download Multiple records its downloading the last one record only.

for example:

If I click on two invoices called,

  • Invc-00000001 (with Attachments) it should download the InvoicePDF
  • Invc-00000002 (with Attachments) it should download the InvoicePDF

It is only downloading the second Invoice with the name Invc-00000002. I think the problem is with the looping only. I can't able to find.

How to overcome this?

Code snippet is more helpful thanks!!

Here is my code

global class DownloadInvoice 
   {
    // Receive Attachments info from Attachment ParentId
    private static String API_STATUS_NORMAL = '200';

    webService static string getAttachmentByParentId(string sfdcId)
    {

        List<id> ids = new List<id>();
        if(string.isempty(sfdcId))  
        {
            return DownloadInvoiceResponse.errorJson('Parameter sfdcId is required.');
        }

        string[] idsArray = sfdcId.split(',');
        for(integer i=0; i<idsArray.size();i++)
        {
            ids.add(idsArray[i]);
        }


        List<Invoice__c> invList = New List<Invoice__c>();
        invList = [Select id, name, Print_Invoice__c,Account__r.name from Invoice where ID IN: ids];

        List<Attachment> attInsert = new List<Attachment>();

        if(invList.size() > 0)
        {

            for(Invoice__c invc : invList)
            {

                Blob body;

                Attachment[] attachments = [SELECT ParentId FROM Attachment where ParentId IN:ids];

                for (Attachment a : attachments)
                {
                    attchmentParentIds.add(a.ParentId);
                }

                Integer WithAttachCount = [SELECT count() FROM Attachment where ParentId IN:ids AND id !=null]

                for(integer i = 1; i<= invList.size(); i++)
                {

                    if(WithAttachCount > 0 && attchmentParentIds.get(0) == invc.Id)
                    {
                        PageReference pdf = new PageReference('/apex/InvoicePDF?id='+invc.id);
                        body = pdf.getContentAsPDF(); 

                    }else if(WithAttachCount <= 0)
                    {

                        PageReference pdff = new PageReference('/apex/InvoiceIfAttachIsNull?id='+invc.id);
                        body = pdff.getContentAsPDF();
                    }

                }                              
                attach.Body = body;
                attach.name= invc.name +'_Invoice_'+ Datetime.Now() +'.PDF';
                attach.IsPrivate = false;
                attach.ParentId = invc.id;
                attach.contentType = 'application/pdf';
                attInsert.add(attach);     

            }    
       }

      Insert attInsert;
}

2 Answers 2

0

I just finished editing your original post to understand the indentation. I discovered first of all that you were missing at least one curly brace in your post. Further, it appears to me that the code in your final loop isn't being iterated on properly to include the bodies in the attachments.

        for(Invoice__c invc : invList)
        {

            Blob body;

            Attachment[] attachments = [SELECT ParentId FROM Attachment where ParentId IN:ids];

            for (Attachment a : attachments)
            {
                attchmentParentIds.add(a.ParentId);
            }

            Integer WithAttachCount = [SELECT count() FROM Attachment where ParentId IN:ids AND id !=null]

            for(integer i = 1; i<= invList.size(); i++)
            {

                if(WithAttachCount > 0 && attchmentParentIds.get(0) == invc.Id)
                {
                    PageReference pdf = new PageReference('/apex/InvoicePDF?id='+invc.id);
                    body = pdf.getContentAsPDF(); 

                }else if(WithAttachCount <= 0)
                {

                    PageReference pdff = new PageReference('/apex/InvoiceIfAttachIsNull?id='+invc.id);
                    body = pdff.getContentAsPDF();
                }

            }// end for(integer i = 1; i<= invList.size(); i++)
            // no iteration in the for loop below this line              
            attach.Body = body;
            attach.name= invc.name +'_Invoice_'+ Datetime.Now() +'.PDF';
            attach.IsPrivate = false;
            attach.ParentId = invc.id;
            attach.contentType = 'application/pdf';
            attInsert.add(attach);     

        }    
   }

I think you want to adjust your code to look more like the following to bulk your queries where possible and create maps for later use:

global class DownloadInvoice 
   {
    // Receive Attachments info from Attachment ParentId
    private static String API_STATUS_NORMAL = '200';

    webService static string getAttachmentByParentId(string sfdcId)
    {

        List<id> ids = new List<id>();
        if(string.isempty(sfdcId))  
        {
            return DownloadInvoiceResponse.errorJson('Parameter sfdcId is required.');
        }

        string[] idsArray = sfdcId.split(',');

        for(integer i=0; i<idsArray.size();i++)
        {
            ids.add(idsArray[i]);
        }

        List<Invoice__c> invList = New List<Invoice__c>();

        invList = [Select id, name, Print_Invoice__c,Account__r.name from Invoice where ID IN: ids];

        if(invList.size() > 0)
        {


            for(Invoice__c invc : invList)
            {
                for (Attachment a : attachments)
                {
                    attchmentParentIds.add(a.ParentId);
                }
            }

            // create map of invlist to attach, then another map of attach to count

            list<Attachment>attach = [SELECT ParentId, Name FROM Attachment where ParentId IN:ids];

            list<AggregateResult>AttachCount = [SELECT count(), ParentId, Name FROM Attachment where ParentId IN:ids AND Name !=null];

            map<Id,integer>Parent2AttachCount = new map<Id,Integer>();

            for(AggegateResult ac:AttachCount){
                Parent2AttachCount.put<ac.ParentId,ac.count()>;
            }

            for(Attachment a:attach){
                Parent2Name.put<a.ParentId,a.Name>;
            }

            List<Attachment> attInsert = new List<Attachment>();

            Blob body;

            for(Invoice__c invc : invList)
            {

                if(attchmentParentIds.get(invc.Id) == invc.Id && Parent2AttachCount.get(invc.Id) > 0 )
                {

                    PageReference pdf = new PageReference('/apex/InvoicePDF?id='+invc.id);
                    body = pdf.getContentAsPDF(); 
                    attach.Body = body;
                    attach.name= Parent2Name.get(invc.Id) +'_Invoice_'+ Datetime.Now() +'.PDF';
                    // Note: +'_Invoice_' in the above may be optional, but the original 
                    // Name should presumably match your file with just a different date.
                    attach.IsPrivate = false;
                    attach.ParentId = invc.id;
                    attach.contentType = 'application/pdf';
                    attInsert.add(attach);  

                }else if(WithAttachCount <= 0)
                {

                    PageReference pdf = new PageReference('/apex/InvoiceIfAttachIsNull?id='+invc.id);
                    body = pdf.getContentAsPDF();
                    attach.Body = body;
                    attach.name= invc.name +'_Invoice_'+ Datetime.Now() +'.PDF';
                    // Here I'm assuming you need to create a new invoice. Adjust as above
                    // if that's not the case. 
                    attach.IsPrivate = false;
                    attach.ParentId = invc.id;
                    attach.contentType = 'application/pdf';
                    attInsert.add(attach);     

                }

            }                              

            Insert attInsert;    
       }

    }  

}

Note: The above is untested and based entirely on the code you've supplied. I suggest you add debug statements as appropriate to make certain it's doing what you want it to do.

0

Your code is far too complicated, I rewrote it as follows to avoid unnecessary SOQLs and crisper condition testing. Using the subselect on the INvoice query gets you the count of Attachments

webservice static String getAttachmentByParentId(string sfdcIdsParm) {

    String[] invoiceIdList = String.isEmpty(sfdcIdsParm) ? new List<String>() : sfdcIdsParm.split(',');
    Attachment[] attInsList = new List<Attachment>();
    for (Invoice inv : [select id,name,print_invoice__c,account__r.name, 
                           (select id from Attachments )
                           from Invoice where id IN :invoiceIdList]) {

        Blob body = inv.attachments.size() == 0
                        ? new PageReference('/apex/InvoiceIfAttachIsNull?id='+inv.id).getContentAsPdf()
                        : new PageReference('/apex/InvoicePDF?id='+inv.id).getContentAsPdf();
        attInsList.add(new Attachment(  body = body,
                                        name = inv.name + '_Invoice_'+Datetime.now()+'.pdf',
                                        isPrivate = false,
                                        parentId = inv.id,
                                        contentType = 'application/pdf');
    }
    insert attInsList;
    return invoiceIdList.size() == 0 
            ? DownloadInvoiceResponse.errorJson('Parameter sfdcid is required')
            : 'some OK reponse json';


}
3

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .