Docusign embedded sigin - Merge field is not working - salesforce

I am using embedding signing from salesforce using apex toolkit. I could not merge fields from salesforce. I am trying to prepopulate firstname and lastname. I tried with customtabs and customfields. Custom tab is repeating the same value for all the tabs and custom field is not working. Can someone help pls.
contact c =[select firstName,lastname, Envelope_Id__c from contact where id = :currentUser.contactId];
string EnvelopeId='';
Id mySourceId = currentUser.ContactId; // The ID of the initiating Salesforce object
String conStr = (String) currentUser.ContactId + '~Contact';
ContractType__mdt ContractType= [SELECT label, Envelope_Configuration__c,External_Document_Id__c
FROM ContractType__mdt where Envelope_Configuration__c =:application.Envelope_Configuration__c limit 1];
string templateId= ContractType.External_Document_Id__c;
/*
dfsle.Envelope dsEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
new dfsle.Entity(mySourceId)) // The initiating Salesforce entity--current SF user (salesperson)
.withDocuments(new List<dfsle.Document> {
dfsle.Document.fromTemplate(dfsle.UUID.parse(templateId), description)
})
.withRecipients(new List<dfsle.Recipient> {
dfsle.Recipient.newEmbeddedSigner() // An embedded signer
}
);
if(!Test.isRunningTest()){
// Send the envelope.
dsEnvelope = dfsle.EnvelopeService.sendEnvelope(
dsEnvelope, // The envelope to send
true // Send now?
);
EnvelopeId= String.valueOf(dsEnvelope.docuSignId);
}*/
dfsle.Envelope myEnvelope = dfsle.EnvelopeService.getEmptyEnvelope(
new dfsle.Entity(mySourceId));
// The initiating Salesforce entity (an opportunity).
dfsle.Tab myTextFNAMETab = new dfsle.TextTab()
.withRequired(true) // Signer must enter value
.withValue(c.firstName)
.withReadOnly(false)
.withName('FName')
// .withAnchor(new dfsle.Tab.Anchor('Legal Name', true, true, null, true, true, 'pixels', 60, -4));
.withPosition(new dfsle.Tab.Position(
1, // The document to use
1, // Page number on the document
149, // X position
240, // Y position
80, // 100 pixels wide
null)); // Default height
dfsle.Tab myTextLNAMETab = new dfsle.TextTab()
.withRequired(true) // Signer must enter value
.withValue(c.lastName)
.withReadOnly(false)
.withName('LName')
// .withAnchor(new dfsle.Tab.Anchor('Legal Name', true, true, null, true, true, 'pixels', 60, -4));
.withPosition(new dfsle.Tab.Position(
1, // The document to use
1, // Page number on the document
230, // X position
240, // Y position
80, // 100 pixels wide
null)); // Default height
dfsle.Recipient myRecipient2 = dfsle.Recipient.newEmbeddedSigner();
myRecipient2.withTabs(new List<dfsle.Tab> {myTextLNAMETab});
//dfsle.Recipient myRecipient2 = dfsle.Recipient.newEmbeddedSigner();
//add Recipient to the Envelope
myEnvelope = myEnvelope.withRecipients(new List<dfsle.Recipient> { myRecipient2});
myEnvelope = myEnvelope.withEmail('Testt Email Subject', 'Test Email Message');
//myTemplateId contains the DocuSign Id of the DocuSign Template
dfsle.UUID myTemplateId = dfsle.UUID.parse(templateId);
//create a new document for the Envelope
dfsle.Document myDocument = dfsle.Document.fromTemplate(
myTemplateId, // templateId in dfsle.UUID format
'Enrollment Agreement'); // name of the template
dfsle.CustomField myField = new dfsle.CustomField ('text', 'DSFSSourceObjectId', conStr, null, false, false);
//add document to the Envelope
myEnvelope = myEnvelope.withDocuments(new List<dfsle.Document> { myDocument })
.withCustomFields(new List<dfsle.CustomField> {myField});
if(!Test.isRunningTest()){
myEnvelope = dfsle.EnvelopeService.sendEnvelope(
myEnvelope, // The envelope to send
true); // Send now?

I'm assuming you're trying to populate existing fields in your template, if that's the case:
// This will populate all the fields with data label name 'FName':
dfsle.Tab prefill_firstname = new dfsle.TextTab()
.withValue(myContact.firstName)
.withDataLabel('FName');
// This will populate all the fields with data label name 'LName':
dfsle.Tab prefill_lastname = new dfsle.TextTab()
    .withValue(myContact.lastName)
    .withDataLabel('LName');
// Otherwise, if you just want to a create new recipient's first & last name tabs instead of populating field:
dfsle.Tab New_firstname_tab = new dfsle.FirstNameTab()
      .withName('AdditionLastName')
      .withPosition(new dfsle.Tab.Position(
      1, // The document to use
      1, // Page number on the document
      400, // X position
      240, // Y position
      80, // 100 pixels wide
      null)); // Default height
dfsle.Tab New_lastname_tab = new dfsle.LastNameTab()
      .withName('AdditionLastName')
      .withPosition(new dfsle.Tab.Position(
      1, // The document to use
      1, // Page number on the document
      500, // X position
      240, // Y position
      80, // 100 pixels wide
      null)); // Default height
dfsle.Recipient myRecipient2 = dfsle.Recipient.newEmbeddedSigner();
  myRecipient2.withTabs(new List<dfsle.Tab> {prefill_firstname,prefill_lastname,New_firstname_tab,New_lastname_tab});
  myRecipient2.withRole('Manager');  // remember to specify the role that match the Role in your template.
As for the envelope Custom Fields:
dfsle.CustomField myField = new dfsle.CustomField ('text', 'DSFSSourceObjectId', conStr, null, false, false);
Note: Envelope Custom Fields aren't directly visible to a recipient during a signing session, since you have set the show parameter to 'false', it will not be included in the Certificate of Completion. However, it should still be visible through web console reporting and API:
https://www.docusign.com/blog/dsdev-trenches-tabs-and-custom-fields

Related

Multiple File search in varying level of directories in perl

I have a directory structures as follows. I want to have only the first path, not the paths which are present after the first file in the report.
I also don't want to check further in that report after getting first file, thus want to save time.
structure for directory:
Report 1
A--B--C--D--E--abc.txt--->needed this
A--B--C--D--E--F--abc.txt avoid this
Report 2
A--B--C--D--E--Q--R--abc.txt needed this, as it is single in its report.
Report 3
A--H--I--J--abc.txt --needed this
Report 4
A--B--C--D--M--abc.txt needed this
A--B--C--D--M--N--abc.txt avoid this
.
.
.
.
millions of such reports.
Directory A contains millions of reports. Each report contains multiple files and subdirectories. Each report have abc.txt in one of the path present
and same path post abc.txt level ,may contain other subdirectories inside the path which also have have abc.txt.
Note:
Reports are of varying level of subdirectories
     
open my $fh, '-|', 'find', $maindirectory, '-type','d' or die "cant open pipes $! \n";
            while (<$fh>) {
                my $dirpath = $_;
                chomp $dirpath;
                if(-d $dirpath) {
                    $filewithpath = File::Spec->catfile( $dirpath, "abc.txt" );
                    if (-e $filewithpath) {
                        push #patharray, $filewithpath;
                    }
                }
}
I think you want the abc.txt files
which are nearest to the
main directory for a common initial path.
That is, you want to avoid looking for
A/B/C/../F/abc.txt if A/B/C/abc.txt
has been found.
This criteria will select files A/H/I/J/abc.txt,
A/B/C/D/M/abc.txt, A/B/C/D/E/abc.txt for your
sample directory tree.
And not A/B/C/D/E/Q/R/abc.txt,
which you have marked as needed in your sample,
because the file A/B/C/D/E/abc.txt has already
been found above it in the directory hierarchy.
You can do this in perl using:
use strict;
use warnings;
use File::Find;
my $maindirectory = "A";
#replace with actual main directory name
File::Find::find(
sub {
if ( -d && -f "$_/abc.txt" ) {
$File::Find::prune = 1;
process_path_of_needed_file("$File::Find::name/abc.txt");
}
},
$maindirectory
);
See https://perldoc.perl.org/File/Find.html

How can I parse json array from json object?

I have a json object being returned from a get request in reactjs. I am wanting to get key and value items from this.
{"return":"Success",
"Items": [
{"Name":"centracore", "Type":"rollover" ,  "Os":"Windows",  "Level":"1", "Language_Used":"Assembly", "Size":"4mb"},
{"Name":"centracore", "Type":"Atype" ,   "Os":"Linux"  ,  "Level":"3", "Language_Used":"C++"     , "Size":"4mb"},
{"Name":"centracore", "Type":"random" ,  "Os":"OSX"    ,  "Level":"2", "Language_Used":"C"       , "Size":"4mb"}
]}
I noticed I can access the values manually using the code below.
Keep in mind, that this.state.stuff is holding my json object. Is my format json format bad for what I am trying to do?
if(this.state.authenticated ){
        {this.GetPage.bind(this)}
        let x = this.state.stuff; Object.entries(this.state.stuff).map((type,item) => {
        console.log(type[1][0])
        console.log(type[1][1])
        console.log(type[1][2])
      })
As far as I understand you want to be able to get the key and values within the Object Items arrays, so you need to map over items array and then the key, values from the obtained item with Object.entries()
You can do it like
if(this.state.authenticated ){
{this.GetPage.bind(this)}
this.state.stuff.Items.map((item, index) => {
Object.entries(item).forEach([key, value], () => {
console.log(key, value)
})
})
Working example
var obj = {"return":"Success",
"Items": [
{"Name":"centracore", "Type":"rollover" , "Os":"Windows", "Level":"1", "Language_Used":"Assembly", "Size":"4mb"},
{"Name":"centracore", "Type":"Atype" , "Os":"Linux" , "Level":"3", "Language_Used":"C++" , "Size":"4mb"},
{"Name":"centracore", "Type":"random" , "Os":"OSX" , "Level":"2", "Language_Used":"C" , "Size":"4mb"}
]}
obj.Items.map((item, index) => {
console.log( item);
Object.entries(item).forEach(([key, value]) => {
console.log(key, value)
})
})
JSFIDDLE

Can I sort children different than parent in CakePHP 3 threaded query?

I have a questions regarding threaded comments. Is it possible to order comments DESC and child comments ASC from this query (or table level) or should I make a after query modification?
Below you can find my query that orders all to DESC.
```
$comments = $this->Comments
        ->find('threaded', ['order' => ['Comments.created' => 'DESC']])
           ->contain(['Users'])
           ->matching(
               'BoardItems',
               function ($q) use ($boardItemId) {
                   return $q->where(
                       [
                           'BoardItems.id' => $boardItemId
                       ]
                   );
               }
           )
           ->all();
```
On SQL Level
You should be able to apply the solution suggested in MySql: ORDER BY parent and child, which
uses COALESCE to group/sort the parents first
groups the children by testing for a non-NULL parent ID
sorts the grouped children
In your case you'd sort by created instead of id, ie something like
ORDER BY
COALESCE(Comments.parent_id, Comments.created) DESC,
Comments.parent_id IS NOT NULL,
Comments.created ASC
To build this in a proper query builder-ish fashion, you'd have to use the order() and orderDesc() methods, so that you can use query expressions, something along the lines of
$query = $this->Comments
->find('threaded');
$comments = $query
// ->contain(...)
// ->matching(...)
// COALESCE(Comments.parent_id, Comments.created) DESC
->orderDesc($query->func()->coalesce([
'Comments.parent_id' => 'identifier',
'Comments.created' => 'identifier'
]))
// Comments.parent_id IS NOT NULL
->order($query->newExpr()->isNotNull('Comments.parent_id'))
// Comments.created ASC
->order(['Comments.created' => 'ASC'])
->all();
See also
Cookbook > Database Access & ORM > Query Builder > Selecting Data
Cookbook > Database Access & ORM > Query Builder > Using SQL Functions
Cookbook > Database Access & ORM > Query Builder > Advanced Conditions
On PHP level
Sorting things afterwards would be an option too, for example using a recursive result formatter:
$sortChildren = function($row) use (&$sortChildren) {
if (!empty($row['children'])) {
$row['children'] =
collection($row['children'])
->sortBy('created', SORT_ASC)
->map($sortChildren)
->toArray();
}
return $row;
};
$comments = $this->Comments
->find('threaded')
// ->contain(...)
// ->matching(...)
->order(['Comments.created' => 'DESC'])
->formatResults(function ($results) use ($sortChildren) {
return $results->map($sortChildren);
})
->all();
This would retrieve everything sort descending, and then sort all children arrays ascending by the created field. Similarily you could sort things before you output/use them in your views, depending on what exactly you're planning to do with the results.
If you want to keep things in the table, you could for example wrap this all up in a custom finder and/or retrieve the sort closure via a method on your table class.
See also
Cookbook > Collections > Sorting
Cookbook > Collections > Iterating

Backbone fetch (or sync) doesn't look up right url

I'm trying to get some data from the node server, which works fine, but when I try to GET data via the Backbone fetch (or sync), the request fails. I noticed that, for some reason, actual request is wrong: 'GET http://localhost:3000/socket.io/1/' where it should be 'GET http://localhost:3000/cars', since '/cars' is the value of the URL field that Backbone uses by convention for these operations. These are the relevant modules:
var Backbone = require("backbone");
var Car = require('models/car');
var Cars = Backbone.Collection.extend ({
model: Car,
url: '/cars',
// Unselect all Car Cards
resetSelected: function() {
for (var i=1; i<=this.length; ++i) {
var carcard=this.get(i);
carcard.set({"selected": false});
console.log(carcard.attributes.name + ' unselected');
}
},
// Select a specific model from the collection
selectByID: function(id) {
this.resetSelected();
var carcard = this.get(id);
carcard.set({"selected": true});
console.log(carcard.attributes.name + " selected");
return carcard.attributes.id;
}
});
module.exports = Cars;
And a model:
var Backbone = require("backbone");
var Car = Backbone.Model.extend({
defaults: {
year: 2011,
brand: "Brand",
model: "Model",
name: "Car Name",
pictureFle: "img/car.jpg",
kmTraveled: 0,
litresSpent: 0,
selected: false
},
});
module.exports = Car;
I tried to populate the collection like this:
var cars = new Cars();
cars.fetch();
but, as I explained, failed. Any ideas what the problem could be?

Sencha Touch 2 store get record

I have a problem.
I have 2 store files (1 event and 1 places). I'm loading these stores from a database. Now the problem is that in the event store there is a field called {id_place}. This field contains a number which is also a number in the places store. Now what I need to do is get the name from the place of the {id_place}. So the {name} is a field in the places store. So what I need is a function to get a record from another store and then get the {name} from that store. So I send the id_place to the placestore, then I need to find the record with that id and I need to get the field {name} from that record. I don't know if I'm making sense, it's kinda hard to explain. I hope this can be done.
Thanks in advance!
Edit:
showPlace: function(id_place){
var placeUrl = 'http://admin.hishanghai.info/sencha/places.php?action=read&callback=callback&id=' + id_place;
store = new Ext.data.Store({
model: 'android.model.Placesmodel',
autoLoad: true,
proxy: {
type: 'scripttag',
url: placeUrl,
reader: {
type: 'json',
rootProperty: 'place'
},
extraParams: {
action: 'read'
}
}
})
//var naam = Ext.getStore('Placesstore').getById('id_place').get('name')
//var Record = store.getAt(id_place);
//var naam = store.getById('id_place').get('name');
var naam = store.get('name');
return naam;
}
This code creates a store with the info from 1 record. Now I only need to access the name field. how do i do that?
found it:
showPlace: function(id_place){
var placesstore = Ext.getStore('Placesstore');
var i =0;
var placeid = 0;
var aRecord;
while(placeid != id_place){
aRecord = placesstore.getAt(i);
placeid = aRecord.data.id;
i+=1;
}
var naam = aRecord.data.name;
return naam;
}

Resources