Thursday, 23 February 2012

Docusign E-Signature

Docusign provides e-signature to documents. We can send document to as many recipients and get their signs using Docusign. This functionality can be accessible through its Member console. If you want to integrate Docusign with your application, you can use its API.
Here in the blog I had used its demo service. You can get API from:


When we send a document to Docusign for sign, it creates an envelope. This Envelope contains document, recipients who will review or sign the document, Tabs with where to put signature, or Custom tab.

Now let’s start the process of sending documents and sign them through API.

Add the above link to service reference of the project. (Here, service reference name is “DocuSignWeb”)

How to send document:


CreateAndSendEnvelope  function of API Service is used to send the document to Docusign. To use this function follow steps.

Step 1:  Create Recipients


Docusing creates two types of Users: Embedded and Remote

Embedded user requires authentication while retrieving document, where remote user is not allowed to get the document. Whole process is handled through email in remote user.

DocuSignWeb.Recipient r = new DocuSignWeb.Recipient();

r.Email = email;

r.UserName = firstName + " " + lastName;

r.Type = DocuSignWeb.RecipientTypeCode.Signer;

r.RequireIDLookup = false;

r.ID=1.ToString(System.Globalization.CultureInfo.InvariantCulture);

If you are creating embedded user then it will require CaptiveInfo:

r.CaptiveInfo = new DocuSignWeb.RecipientCaptiveInfo();

r.CaptiveInfo.ClientUserId = clientUserId;

r.SignatureInfo = new DocuSignWeb.RecipientSignatureInfo();

r.SignatureInfo.SignatureInitials = (firstName.Length > 0 ? firstName.Substring(0, 1) : "") + (lastName.Length > 0 ? lastName.Substring(0, 1) : "");

r.SignatureInfo.FontStyle = DocuSignWeb.FontStyleCode.BradleyHandITC;

r.SignatureInfo.SignatureName = firstName + " " + lastName;

CaptiveInfo.ClientUserId is unique for each envelope. (E.g. SessionId). It is used for authentication when we retrieve this document.



Step 2: Add Document


DocuSignWeb.Document doc= new Document();

doc.ID = 1.ToString(CultureInfo.InvariantCulture);

doc.Name = documentName;

using (System.IO.FileStream streamReader = new System.IO.FileStream(fullFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))

{

      byte[] pdfBytes = new byte[streamReader.Length];

      streamReader.Read(pdfBytes, 0, (int)streamReader.Length);

      doc.PDFBytes = pdfBytes;

}


Step 3: Create Tabs


DocuSignWeb.Tab tab=new DocuSignWeb.Tab();

tab.DocumentID= doc.ID;

tab. RecipientID = recipient.ID;

tab.Name = name;

tab.TabLabel = name;

tab.PageNumber = pageNumber;

tab.XPosition = XPosition;

tab.YPosition = YPosition;

tab.Type = DocuSignWeb.TabTypeCode.SignHere


If Tab is Custom Type then,


tab.Type = DocuSignWeb.TabTypeCode.Custom;

tab.SharedTab = true;

tab.Value = value;           


If SharedTab property is true, that means all recipients can change the value of that tab.

Step 4: Create Credential


DocuSignWeb.APIServiceSoapClient apiService = new DocuSignWeb.APIServiceSoapClient("APIServiceSoap", "https://demo.docusign.net/api/3.0/api.asmx");

apiService.ClientCredentials.UserName.UserName = "[" + IntegratorsKey + "]";

apiService.ClientCredentials.UserName.UserName += APIUserEmail;

apiService.ClientCredentials.UserName.Password = Password;


This credentials you can get from your Member console of Docusign site.

Step 5:  Create Envelope


DocuSignWeb.Envelope envelope = new DocuSignWeb.Envelope();

envelope.Subject = "DocuSign Test Document.";

envelope.EmailBlurb = "Hello!  This was submitted from a sample application";

envelope.Recipients = lstofRecipients;

envelope.AccountId = AccountId;

envelope.AllowMarkup = true;

// assign the document array

envelope.Documents = new DocuSignWeb.Document[lstofdoc.Length];

for (int i = 0; i < documents.Length; ++i)

{

            envelope.Documents[i] = lstofdoc[i].Document;

       }


// assign the tabs to the envelope

envelope.Tabs = lstoftabs.ToArray();

envelope.CustomFields = fields;

envelope.EnvelopeAttachment = attachments;

 DocuSignWeb.EnvelopeStatus envStatus = apiService.CreateAndSendEnvelope(envelope);


With this document is sent to Docusign.

How to sign document:


RequestRecipientToken function is used to retrieve URL of the document stored in Docusign. We can pass this URL to iframe in our aspx page. To use this function follow steps.

Step 6: Create RequestRecipientTokenAuthenticationAssertion


public DocuSignWeb.RequestRecipientTokenAuthenticationAssertion MakeRecipientTokenAuthAssert(string assertionId)

        {

            DocuSignWeb.RequestRecipientTokenAuthenticationAssertion assert = new DocuSignWeb.RequestRecipientTokenAuthenticationAssertion();

            assert.AssertionID = assertionId;

            assert.AuthenticationInstant = DateTime.Now;

            assert.AuthenticationMethod = DocuSignWeb.RequestRecipientTokenAuthenticationAssertionAuthenticationMethod.Password;

            assert.SecurityDomain = "Loan Demo";

            return assert;

        }


AssertionId value is informational for you to refer to the recipient. It can be ApplicaionId.

Step 7: Create RequestRecipientTokenClientURLs


public DocuSignWeb.RequestRecipientTokenClientURLs StandardUrls(System.Uri urlBase, string userName)

        {

            DocuSignWeb.RequestRecipientTokenClientURLs urls = new DocuSignWeb.RequestRecipientTokenClientURLs();

            urls.OnSigningComplete = urlBase + "?event=SignComplete&uname=" + userName;

            urls.OnViewingComplete = urlBase + "?event=ViewComplete&uname=" + userName;

            urls.OnCancel = urlBase + "?event=Cancel&uname=" + userName;

            urls.OnDecline = urlBase + "?event=Decline&uname=" + userName;

            urls.OnSessionTimeout = urlBase + "?event=Timeout&uname=" + userName;

            urls.OnTTLExpired = urlBase + "?event=TTLExpired&uname=" + userName;

            urls.OnIdCheckFailed = urlBase + "?event=IDCheck&uname=" + userName;

            urls.OnAccessCodeFailed = urlBase + "?event=AccessCode&uname=" + userName;

            urls.OnException = urlBase + "?event=Exception&uname=" + userName;

            return urls;

        }

From here you could specify a different redirect target for each status event - signing completed, cancelled, error, etc. We just use one page with different Querystring params to indicate the event.

Step 8: Get Recipient object who is requesting for document


Follow Step 1

Step 9:  Request for document


Get DocuSignWeb.APIServiceSoap as Step 4.

And call:          

apiService.RequestRecipientToken(_envelopeId, recipient.CaptiveInfo.ClientUserId,  recipient.UserName, recipient.Email, assert, clientURLs);



This function will return URL for the document to be signed. From here recipient can sign document, decline to sign, sign later.           

Thanks,

Posted By: Priyanka Shah

MVC Telerik Upload Control

Telerik Upload control provides multiple files upload simultaneously sync/async.
 @(Html.Telerik().Upload()

        .Multiple(true)

        .Name("UploadFile")

        .ClientEvents(t => t.OnError("UploadFile.error").OnUpload("UploadFile.Upload"))

        .Async(t => t.AutoUpload(false)

  .Remove("Remove", "UploadFiles")

         .Save("Save", "UploadFiles")))

Many times we required to get the status or file Id in database as return value after uploading. Here, when file is uploaded and you return any status message of from save function it will interpret as error in uploading file.
To get this functionality, go through bellow.

1:  Get Object

Get the object of uploading control and override its existing method which generates error message.

var r = $("#UploadFile").data("tUpload");

r._alert = function (ee) { };

$("#UploadFile").data("tUpload", r);

_alert() is the function which generates error message when response from save() is non empty.

2:   Get response text from Save()

As we return status, it will fire UploadFile.error().
UploadFile.error = function (e) {

    UploadFile.filename = e.files[e.files.length - 1].name;

    UploadFile.statusMsg = e.XMLHttpRequest.responseText;

    if (e.XMLHttpRequest.responseText.indexOf("Success") < 0) {

        UploadFile.Status = "error";

    }

    else {

        UploadFile.Status = "success";

    }

};


XMLHttpRequest.responseText is the value of status sent from Save() by which you can distinguish with actual uploading error or the successful status message.


3: Change Classes to get correct output

Here, file is uploaded success fully. Though it shows with red mark as error.

 We need to work on Jquery to get correct output:

$(".t-file .t-fail").removeClass("t-fail").addClass("t-success");

$(".t-file .t-success").html("uploaded");

$(".t-file .t-success").parent().find('.t-retry').removeClass("t-retry").addClass("t-delete");

$(".t-file .t-success").parent().find(".t-delete").parent().html("<span class='t-icon t-delete'></span>delete”);

4: Override function _removeFileEntry()  to get more functionality

When you click on delete button it will just remove the file list from div, and call Remove() of controller. But if you want to handle some features from Jquery, like remove FileId from list of FileId stored in hidden field, override _removeFileEntry() of telerik uploader as:

var r = $("#UploadFile").data("tUpload");

r._removeFileEntry = function (v) {};

$("#UploadFile").data("tUpload", r);