peterzog | Posts: 109

Anchoring to PDF Fields

0 votes

I am trying to find documentation on we can create fields on a PDF that OSS can anchor to.  I have Adobe Acrobat CC and can add text fields to a PDF file.  I am trying to anchor to the field by the name I gave those text fields and it doesn't appear the OSS can find them.  Am I adding these fields to the PDF incorrectly? 

I am trying to anchor via the Salesforce management package and the APEX SDK, with no luck.


Duo_Liang | Posts: 3776

Reply to: Anchoring to PDF Fields

0 votes

Hi Peter,

 

If we are talking about Position Extraction (use PDF form field name to anchor OneSpan Sign fields), with APEX SDK, you can use below sample code and PDF as a quick start:
 

 public static void test1013(){
             OneSpanSDK sdk = new OneSpanSDK();
            //Create package
            OneSpanAPIObjects.Package_x pkg = new OneSpanAPIObjects.Package_x();
            pkg.name = 'Test Postiion Extraction - ' + Datetime.now().format();
            pkg.status = OneSpanAPIObjects.PackageStatus.SENT;

            //Create Roles
            String roleId1 = 'Signer1';
            OneSpanAPIObjects.Role role1 = new OneSpanAPIObjects.Role();
            role1.signers = sdk.createRolesSigner('FirstName', 'LastName', '[email protected]', 'CEO', 'ABC Bank');
            role1.id = roleId1;
            role1.name = roleId1;
            pkg.roles = new List<OneSpanAPIObjects.Role>{role1};    //add role
                
            //Prepare Documents Blob   
            String document1Name = 'Document1';   
            StaticResource sr = [SELECT Id, Body FROM StaticResource WHERE Name = 'test_position_extraction' LIMIT 1];   
            Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
            documentBlobMap.put(document1Name, sr.Body);   
        
            //Create Document Metadata   
            OneSpanAPIObjects.Document document1 = new OneSpanAPIObjects.Document();   
            document1.name = document1Name;   
            document1.id = document1Name;   
            document1.extract = true;     //document level extraction:true   
            OneSpanAPIObjects.Approval approval1 = new OneSpanAPIObjects.Approval();   
            approval1.role = roleId1;   
            approval1.name = 'Approval1';   
            //signature
            OneSpanAPIObjects.Field field1 = new OneSpanAPIObjects.Field();   
            field1.extract = true;   
            field1.name = 'Signature1';   //matches the form field name in PDF
            field1.type = 'SIGNATURE';   
            field1.subtype = 'FULLNAME';   
            
            //label field
            OneSpanAPIObjects.Field field2 = new OneSpanAPIObjects.Field();   
            field2.extract = true;   
            field2.name = 'SignerName1';   //matches the form field name in PDF
            field2.type = 'INPUT';   
            field2.subtype = 'LABEL';   
            field2.value= 'some value here';         //display value

            
            //Link field to approval, approval to document, document to package
            approval1.fields = new List<OneSpanAPIObjects.Field>{field1,field2};   
            document1.approvals = new List<OneSpanAPIObjects.Approval>{approval1};   
            pkg.documents = new List<OneSpanAPIObjects.Document>{document1};  
  
            
            //Send package One Step
            String packageId = sdk.createPackage(pkg,documentBlobMap);

            System.debug('PackageId: ' + packageId);

      }

 

As you may have noticed, there are two PDF form fields "Signature1" and "SignerName1" which have to be the same as the OSS field names. And remember not to specify the approval and field ID in code.

After creation, the PDF looks like this during Signing Ceremony:

10-13-1

I will also post the equevalent steps in SFDC connector in a short time.

 

Duo


Attachments
Duo_Liang | Posts: 3776

Reply to: Anchoring to PDF Fields

0 votes

Hi Peter,

 

Continue with SFDC connector experience:
 

 

Step1: create a Convention and Add a Recipient Label ("Signer1" in our example)

1

Step2: click into Recipient Label and add two Text Tags (this text tag is different from the Text Tag field, in SFDC, text tag just generally means how you want to put the signatures and fields)

We will be about to use the same sample PDF as attached above, so we will need to specify the "Form Field Name" as "Signature1" and "SignerName1" as resembled below:

5

6

Step3: Return to the Convention level, and create a new Field Mapping - because our label field needs to read data from a SFDC object, field mapping exactly serves in this scenario.

Put the same field name "SignerName1" as the Field Reference name and select the related object field

4

Step4: take ad-hoc creation for example, select the SFDC object in the main screen where you want to read the data from:

2

In Advanced Options tab, select the convention we just created and optionally toggle on the auto-prepare, this saves you time from clicking the "Prepare" button

3

 

In the transaction detail page, add a recipient, and give the same role name "Signer1" as well as select the Recipient Label "Signer1" from the dropdown.

 

 

3

 

Once you save then send the transaction, you will see the similar output as the integration approach with APEX code.

 

Duo


peterzog | Posts: 109

Reply to:

0 votes

Thanks for the quick start! Regarding the APEX SDK approach, I'd am trying to make a dynamic framework via a custom object/record that represents each form for us.

1) CALL: Create DRAFT Package

2) CALL (4x): Create 4 roles via 4 separate calls (dynamic)

3) CALL: Query for document, assign 4 approval to the 4 roles respectively, link fields to approval, approvals to document and document to package

4) CALL: Send Document

If that makes sense (I would not be surprised if I am not making sense), is that possible?  Or do I need to do a position transaction in a single call?

Peter


peterzog | Posts: 109

Reply to:

0 votes

I am asking because I am having trouble getting passed an error that says "error.validation.sendPackage.noApprovals".  This occurs after I updated your code to create a draft package and then update to send - like this:

 

OneSpanSDK sdk = new OneSpanSDK();
            //Create package
            OneSpanAPIObjects.Package_x pkg = new OneSpanAPIObjects.Package_x();
            pkg.name = 'Test Postiion Extraction - ' + Datetime.now().format();
            pkg.status = OneSpanAPIObjects.PackageStatus.DRAFT;
      //Send package One Step
            String packageId = sdk.createPackage(pkg);

            System.debug('PackageId: ' + packageId);

            //Create Roles
            String roleId1 = 'Signer1';
            OneSpanAPIObjects.Role role1 = new OneSpanAPIObjects.Role();
            role1.signers = sdk.createRolesSigner('xxxxxx', 'xxxx', '[email protected]', 'CEO', 'ABC Bank');
            role1.id = roleId1;
            role1.name = roleId1;
            pkg.roles = new List<OneSpanAPIObjects.Role>{role1};    //add role
                
            //Prepare Documents Blob   
            String document1Name = 'Document1';   
            StaticResource sr = [SELECT Id, Body FROM StaticResource WHERE Name = 'Agreement' LIMIT 1];   
            Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
            documentBlobMap.put(document1Name, sr.Body);   
        
            //Create Document Metadata   
            OneSpanAPIObjects.Document document1 = new OneSpanAPIObjects.Document();   
            document1.name = document1Name;   
            document1.id = document1Name;   
            document1.extract = true;     //document level extraction:true   
            OneSpanAPIObjects.Approval approval1 = new OneSpanAPIObjects.Approval();   
            approval1.role = roleId1;   
            approval1.name = 'Approval1';   
            //signature
            OneSpanAPIObjects.Field field1 = new OneSpanAPIObjects.Field();   
            field1.extract = true;   
            field1.name = 'clientPrinted1';   //matches the form field name in PDF
            field1.type = 'SIGNATURE';   
            field1.subtype = 'FULLNAME';   
            
            //label field
            OneSpanAPIObjects.Field field2 = new OneSpanAPIObjects.Field();   
            field2.extract = true;   
            field2.name = 'SignerName1';   //matches the form field name in PDF
            field2.type = 'INPUT';   
            field2.subtype = 'LABEL';   
            field2.value= 'some value here';         //display value

            
            //Link field to approval, approval to document, document to package
            approval1.fields = new List<OneSpanAPIObjects.Field>{field1,field2};   
            document1.approvals = new List<OneSpanAPIObjects.Approval>{approval1};   
            pkg.documents = new List<OneSpanAPIObjects.Document>{document1};  
  
            
           //Send package
           pkg.status = OneSpanAPIObjects.PackageStatus.SENT;
         
           sdk.updatePackage(pkg, packageId); 


Duo_Liang | Posts: 3776

Reply to:

0 votes

Hi Peter,

 

It's completely possible! I've modified your code a bit and see the highlighted changes:

 

 public static void test10132(){

            OneSpanSDK sdk = new OneSpanSDK();
            //Create package in DRAFT status
            OneSpanAPIObjects.Package_x pkg = new OneSpanAPIObjects.Package_x();
            pkg.name = 'Test Postiion Extraction - ' + Datetime.now().format();
            pkg.status = OneSpanAPIObjects.PackageStatus.DRAFT;
            String packageId = sdk.createPackage(pkg);

            System.debug('PackageId: ' + packageId);

            //Create Roles
            OneSpanAPIObjects.Role role1 = new OneSpanAPIObjects.Role();   
            role1.id = 'Signer1';   
            role1.signers = sdk.createRolesSigner('John', 'Smith', '[email protected]', 'CEO', 'ABC Bank');   
            sdk.helper.createRole(packageId, role1);
                
            //Prepare Documents Blob   
            String document1Name = 'Document1';   
            StaticResource sr = [SELECT Id, Body FROM StaticResource WHERE Name = 'test_position_extraction' LIMIT 1];   
            Map<String,Blob> documentBlobMap = new Map<String,Blob>();   
            documentBlobMap.put(document1Name, sr.Body);   
            //Create Document Metadata   
            OneSpanAPIObjects.Document document1 = new OneSpanAPIObjects.Document();   
            document1.name = document1Name;   
            document1.id = document1Name;   
            document1.extract = true;     //document level extraction:true   
            OneSpanAPIObjects.Approval approval1 = new OneSpanAPIObjects.Approval();   
            approval1.role = role1.id;   
            approval1.name = 'Approval1';   
            //signature
            OneSpanAPIObjects.Field field1 = new OneSpanAPIObjects.Field();   
            field1.extract = true;   
            field1.name = 'Signature1';   //matches the form field name in PDF
            field1.type = 'SIGNATURE';   
            field1.subtype = 'FULLNAME';   
            //label field
            OneSpanAPIObjects.Field field2 = new OneSpanAPIObjects.Field();   
            field2.extract = true;   
            field2.name = 'SignerName1';   //matches the form field name in PDF
            field2.type = 'INPUT';   
            field2.subtype = 'LABEL';   
            field2.value= 'some value here';         //display value 
            //Link field to approval, approval to document, document to package
            approval1.fields = new List<OneSpanAPIObjects.Field>{field1,field2};   
            document1.approvals = new List<OneSpanAPIObjects.Approval>{approval1};   
            //upload document
            String documentResponse = sdk.createDocuments(packageId, document1 , documentBlobMap );
            
  
            //Send package
            pkg.status = OneSpanAPIObjects.PackageStatus.SENT; 
            sdk.updatePackage(pkg, packageId); 
           }

 

If you choose to build the package dynamically, additional calls will be needed to sync signer(s) and document(s) with the OSS server.

 

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