peterzog | Posts: 109

Add multiple documents to a package

0 votes

Is there an endpoint to add multiple documents to a package? The APEX SDK appears to only have a method to add one at a time. Trying to minimize callouts from SF. 


peterzog | Posts: 109

Reply to: Add multiple documents to a package

0 votes

Is it possible to tie the OneSpanAPIObjects.Document to each DocumentBloblMap?
 

The example provided in the post only accepts a single OneSpanAPIObjects.Document when creating the documents. This is an issue because OneSpanAPIObjects.Document holds all the merged field values. The challenge is that the API is assuming that all the documents will have the same merge field values and in our use case, we are getting different values. 
 

The use case I have is processing many SF records that each need a form signed. Each form (document) will be stamped with the name of its corresponding SF record and I need to put all the documents into a single package. We want to give the signer one link for all the forms they need to sign. We will be creating many packages like these and want to reduce the callouts per package. 


Duo_Liang | Posts: 3776

Reply to: Add multiple documents to a package

0 votes

Hi Peter,

 

If you are looking for reducing the number of outbound calls, especially when uploading multiple documents, you can try this function:

OneSpanSDK.cls > public String createPackage(OneSpanAPIObjects.Package_x pkg, Map<String,Blob> documentBlobMap)

 

An example code should look like below, where I've added two signers, two documents, and each document contains one signature and one label field with different values:

public static void test12_22(){
              OneSpanSDK sdk = new OneSpanSDK();


              //step1: create package with basic info
              OneSpanAPIObjects.Package_x pkg = new OneSpanAPIObjects.Package_x();   
              pkg.name = 'Create Transaction from Salesforce - ' + Datetime.now().format();   
              pkg.description = 'This is an example transaction.';   
              pkg.emailMessage = 'This is an email message.';  
              pkg.status = OneSpanAPIObjects.PackageStatus.SENT;

              //step2: add signers
              //Signer1
              OneSpanAPIObjects.Signer signer1 = new OneSpanAPIObjects.Signer();
              signer1.firstName = '1.firstName';
              signer1.lastName = '1.lastName';
              signer1.email = '[email protected]';
              signer1.name = 'Signer1';
    
              List<OneSpanAPIObjects.Signer> signers1 = new List<OneSpanAPIObjects.Signer>();
              signers1.add(signer1);
    
              OneSpanAPIObjects.Role role1 = new OneSpanAPIObjects.Role();
              role1.signers = signers1;
              role1.name = 'Signer1';
              role1.id = 'Signer1';
              role1.type = 'SIGNER';
              
              
              //Signer2
              OneSpanAPIObjects.Signer signer2 = new OneSpanAPIObjects.Signer();
              signer2.firstName = '2.firstName';
              signer2.lastName = '2.lastName';
              signer2.email = '[email protected]';
              signer2.name = 'Signer2';
    
              List<OneSpanAPIObjects.Signer> signers2 = new List<OneSpanAPIObjects.Signer>();
              signers2.add(signer2);
    
              OneSpanAPIObjects.Role role2 = new OneSpanAPIObjects.Role();
              role2.signers = signers2;
              role2.name = 'Signer2';
              role2.id = 'Signer2';
              role2.type = 'SIGNER';
              
              
              List<OneSpanAPIObjects.Role> roles = new List<OneSpanAPIObjects.Role>();
              roles.add(role1);
              roles.add(role2);
              pkg.roles = roles;
              
              
             //step3: add documents
              
             //blobs
             Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
             StaticResource sr1 = [SELECT Id, Body FROM StaticResource WHERE Name = 'document1' LIMIT 1];   
             documentBlobMap.put('Doc1', sr1.Body); 

             StaticResource sr2 = [SELECT Id, Body FROM StaticResource WHERE Name = 'document2' LIMIT 1];   
             documentBlobMap.put('Doc2', sr2.Body); 
              
            //metadata
            //document1
            OneSpanAPIObjects.Document doc1 = new OneSpanAPIObjects.Document();
            doc1.name = 'Doc1';
            doc1.id= 'Doc1';
              

            OneSpanAPIObjects.Field signature1 = new OneSpanAPIObjects.Field();
            signature1.type = 'SIGNATURE';
            signature1.subtype = 'FULLNAME';
            signature1.page = 0;
            signature1.left = 100;
            signature1.top = 100;
            signature1.width = 150;
            signature1.height = 50;
            
            OneSpanAPIObjects.Field label1= new OneSpanAPIObjects.Field();
            label1.type = 'INPUT';
            label1.subtype = 'LABEL';
            label1.page = 0;
            label1.left = 100;
            label1.top = 300;
            label1.width = 150;
            label1.height = 50;
            label1.value = 'label1 value';
        
            OneSpanAPIObjects.Approval approval1 = new OneSpanAPIObjects.Approval();
            approval1.role = 'Signer1';
            approval1.fields = new List<OneSpanAPIObjects.Field> {signature1 ,label1};
            doc1.approvals = new List<OneSpanAPIObjects.Approval> {approval1};
            
            
            //document2
            OneSpanAPIObjects.Document doc2 = new OneSpanAPIObjects.Document();
            doc2.name = 'Doc2';
            doc2.id= 'Doc2';  

            OneSpanAPIObjects.Field signature2 = new OneSpanAPIObjects.Field();
            signature2.type = 'SIGNATURE';
            signature2.subtype = 'FULLNAME';
            signature2.page = 0;
            signature2.left = 100;
            signature2.top = 100;
            signature2.width = 150;
            signature2.height = 50;
                        
            OneSpanAPIObjects.Field label2= new OneSpanAPIObjects.Field();
            label2.type = 'INPUT';
            label2.subtype = 'LABEL';
            label2.page = 0;
            label2.left = 100;
            label2.top = 300;
            label2.width = 150;
            label2.height = 50;
            label2.value = 'label2 value';
        
            OneSpanAPIObjects.Approval approval2 = new OneSpanAPIObjects.Approval();
            approval2.role = 'Signer2';
            approval2.fields = new List<OneSpanAPIObjects.Field> {signature2 ,label2};
            doc2.approvals = new List<OneSpanAPIObjects.Approval> {approval2};
            
            List<OneSpanAPIObjects.Document> documents = new List<OneSpanAPIObjects.Document>();
            documents.add(doc1);
            documents.add(doc2);
            pkg.documents = documents;

            
              //step4: send package
              sdk.createPackage(pkg, documentBlobMap ); 
}

 

Note:
 

The document name should match the blob name:

             Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
             StaticResource sr1 = [SELECT Id, Body FROM StaticResource WHERE Name = 'document1' LIMIT 1];   
             documentBlobMap.put('Doc1', sr1.Body); 


            OneSpanAPIObjects.Document doc1 = new OneSpanAPIObjects.Document();
            doc1.name = 'Doc1';
            doc1.id= 'Doc1';

 

Duo


peterzog | Posts: 109

Reply to: Add multiple documents to a package

0 votes

This was very helpful! I was up all night implementing and the obstacle I am battling is heap errors. How can we avoid heap issues when generating a lot of docs? Basically I just need to encode the document once because it's the same doc but with different merge field values. Createpackagewithbinaries is creating limits as it assumes each doc in the blob map is unique. 
 

One other question, is there a way to set order of signers with this approach without add another callout?


Duo_Liang | Posts: 3776

Reply to: Add multiple documents to a package

0 votes

Hi Peter,

 

For reusing the same blob, I did a quick test with the same code base above and seems it's working for me:
 

            Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
            
            StaticResource sr = [SELECT Id, Body FROM StaticResource WHERE Name = 'test_position_extraction' LIMIT 1];   
            Blob b = sr.Body;
          
            documentBlobMap.put('document1', b); 
            documentBlobMap.put('document2', b); 

 

For signer index, it's part of the SDK modelling:
 

              //Signer1
              OneSpanAPIObjects.Signer signer1 = new OneSpanAPIObjects.Signer();
              signer1.firstName = '1.firstName';
              signer1.lastName = '1.lastName';
              signer1.email = '[email protected]';
              signer1.name = 'Signer1';
    
              List<OneSpanAPIObjects.Signer> signers1 = new List<OneSpanAPIObjects.Signer>();
              signers1.add(signer1);
    
              OneSpanAPIObjects.Role role1 = new OneSpanAPIObjects.Role();
              role1.signers = signers1;
              role1.name = 'Signer1';
              role1.id = 'Signer1';
              role1.type = 'SIGNER';
              role1.index = 1;

 

Duo


Hello! Looks like you're enjoying the discussion, but haven't signed up for an account.

When you create an account, we remember exactly what you've read, so you always come right back where you left off