Anchoring to PDF Fields
Tuesday, October 12, 2021 at 03:47pmI 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.
Reply to: Anchoring to PDF Fields
Wednesday, October 13, 2021 at 08:42amHi 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:
I will also post the equevalent steps in SFDC connector in a short time.
Duo
Reply to: Anchoring to PDF Fields
Wednesday, October 13, 2021 at 09:16amHi Peter,
Continue with SFDC connector experience:
Step1: create a Convention and Add a Recipient Label ("Signer1" in our example)
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:
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
Step4: take ad-hoc creation for example, select the SFDC object in the main screen where you want to read the data from:
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
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.
Once you save then send the transaction, you will see the similar output as the integration approach with APEX code.
Duo
Reply to: Hi Peter, If we are…
Wednesday, October 13, 2021 at 12:46pmThanks 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
Reply to: Thanks for the quick start!…
Wednesday, October 13, 2021 at 01:24pmI 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);
Reply to: I am asking because I am…
Wednesday, October 13, 2021 at 01:38pmHi 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