Saturday 1 February 2020

DocuSign Integration with Salesforce Using API and Controller

1- Service class for the docusign integration

/**
 * Class Name: EEC_DocusignServiceUtility
 * Purpose: Service class for the docusign integration
 * Created By/Date: Upendra Dubey
 */
public with sharing class EEC_DocusignServiceUtility {
    public static EEC_Config__c docusignConfig = EEC_Config__c.getInstance();
    static String integratorKey = docusignConfig.Secure_Param_Key__c; // integrator key (found on Preferences -> API page)
    static String username = docusignConfig.User_Name__c; // account email (or your API userId)
    static String password = docusignConfig.Password__c; // account password
    static String docusignURL = docusignConfig.Docusign_URL__c; //docusign url
    // construct the DocuSign authentication header
    public static String authenticationHeader =
                    '<DocuSignCredentials>' +
                        '<Username>' + username + '</Username>' +
                        '<Password>' + password + '</Password>' +
                        '<IntegratorKey>' + integratorKey + '</IntegratorKey>' +
                    '</DocuSignCredentials>';
    /*
     * Method Name: sendDocumentForSigning
     * Description: Method to send the document for signing and save the envelope Id on the Transaction_Contact__c
     * @return: List<DocumentInformation>
     * @param: Id, Map<Id, blob>, String
    */
    public static String sendDocumentForSigning(String transactionId, String returnPageURL, Pagereference pdfPage) {
        DocumentInformation documentInformation;
        if(String.isBlank(transactionId)) {
            return '';
        }
        List<SignerInformation> uploadSigners = new List<SignerInformation>();
        Transaction_Contact__c transactionContact = new Transaction_Contact__c();
        for(Transaction_Contact__c tempTransactionContact : [SELECT Id,
                                                                First_Name__c,
                                                                Last_Name__c,
                                                                Email__c,
                                                                Envelope_Id__c
                                                            FROM Transaction_Contact__c
                                                            WHERE Id =: transactionId]) {
            transactionContact = tempTransactionContact;
            SignerInformation signerInformation = new SignerInformation(tempTransactionContact.First_Name__c + ' ' + tempTransactionContact.Last_Name__c, 
                                                                        tempTransactionContact.Email__c, 11'Signature Panel Tag''Signing Date');
            uploadSigners.add(signerInformation);
        }
        /* String emailBody = 'Hi,<br/><br/>Please sign the document for BRC Information by clicking the "Review Document" button above.' +
                               '<br/><br/>Thank You,<br/>'; */
        Blob content = pdfPage.getContentAsPDF();
        documentInformation = sendSigningDocument(EncodingUtil.base64Encode(content), uploadSigners,
                                                      ' '' ''Consent licensee'true, returnPageURL);
        if(String.isNotBlank(documentInformation.envelopeId)) {
            transactionContact.Envelope_Id__c = documentInformation.envelopeId;
            update transactionContact;
        }
        return documentInformation.signingUrl;
    }
    public static String getSigningURL(String envelopeId, String returnPageURL, String signerName,
                                       String signerEmail, Integer recipientId){
        return getSigningURL(authenticate(docusignConfig.Docusign_URL__c, authenticationHeader), envelopeId, returnPageURL,
                                          new SignerInformation(signerName, signerEmail, recipientId, nullnullnull)).signingUrl;                                    
    }
    /*
     * Method Name: sendSigningDocument
     * Description: Method to get signing URL and envelopId of the document
     * @return: DocumentInformation
     * @param: String, String, List<SignerInformation>, String, String, String, Boolean, String, Boolean
    */
    public static DocumentInformation sendSigningDocument(String content, List<SignerInformation> signers,
                                                          String emailSubject, String emailBody, String documentName,
                                                          Boolean isGetURL, String returnPageURL){
        //============================================================================
        // STEP 1 - Make the Login API call to retrieve your baseUrl and accountId
        //============================================================================
        AuthenticationInformation authenticationInformation = authenticate(docusignConfig.Docusign_URL__c, authenticationHeader);
        //============================================================================
        // STEP 2 - Signature Request from Template API Call
        //============================================================================
        HttpRequest request = new HttpRequest();
        http httpCallout = new http();
        HttpResponse response = new HttpResponse();
        String url = authenticationInformation.baseURL + '/envelopes';
        // this example uses XML formatted requests, JSON format is also accepted
        String body =  '<envelopeDefinition xmlns=\'http://www.docusign.com/restapi\'>' +
                       '<AllowMarkup>false</AllowMarkup>' +
                       '<emailSubject><![CDATA[' + emailSubject + ']]></emailSubject><emailBlurb><![CDATA[' + emailBody + ']]></emailBlurb>' +
                       '<documents><document><name>' + documentName + '</name><documentId>1</documentId>' +
                       '<documentBase64>' + content + '</documentBase64>' +
                       '</document></documents>' +
                       '<accountId>' + authenticationInformation.accountId + '</accountId>' +
                       '<status>sent</status>' +
                       '<emailSubject>' + emailSubject + '</emailSubject>' +
                       '<recipients><signers>';
        for(SignerInformation signer : signers){
            body += '<signer><email>' + signer.signerEmail + '</email>' +
                    '<name>' + signer.signerName + '</name><recipientId>' + signer.recipientId + '</recipientId><routingOrder>' +
                    signer.routingOrder + '</routingOrder>' +
                    (isGetURL ? '<clientUserId>' + signer.recipientId + '</clientUserId>' : '') +
                     '<tabs><dateSignedTabs><dateSigned><tabLabel>' + signer.signDateLabel + '</tabLabel><name>' + signer.signDateLabel + '</name>' +
                     '<anchorString>' + signer.signDateLabel + '</anchorString><anchorMatchWholeWord>true</anchorMatchWholeWord><anchorXOffset>0</anchorXOffset>' +
                     '<anchorYOffset>10</anchorYOffset></dateSigned></dateSignedTabs><signHereTabs><signHere><anchorString>' +
                     signer.signLabel + '</anchorString><anchorMatchWholeWord>true</anchorMatchWholeWord><anchorXOffset>0</anchorXOffset><anchorYOffset>0</anchorYOffset>' +
                     '<anchorIgnoreIfNotPresent>false</anchorIgnoreIfNotPresent><anchorUnits>inches</anchorUnits></signHere></signHereTabs></tabs>' +
                    '</signer>';
        }
        body += '</signers></recipients></envelopeDefinition>';
        request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('POST');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/xml');
        request.setHeader('Accept''application/xml');
        request.setHeader('Content-Length', String.valueOf(body.length()));
        if(body.contains('&')){
            body = body.replace('&','&amp;');
        }
        request.setBody(body);
        httpCallout = new http();
        response = new HttpResponse();
        response = httpCallout.send(request);
        String envelopeId = '';
        String uri ='';
        Dom.Document doc = response.getBodyDocument();
        for(Dom.XmlNode node : doc.getRootElement().getChildElements()) {
            if(node.getName() == 'envelopeId') {
                envelopeId = node.getText();
            }
            if (node.getName() == 'uri') {
                uri = node.getText();
            }
        }
        String signingUrl;
        if(isGetURL){
            return getSigningURL(authenticationInformation, envelopeId, returnPageURL, signers.get(0));
        }
        return new DocumentInformation(envelopeId, nullnullnull, signingUrl);
    }
    public static DocumentInformation getSigningURL(AuthenticationInformation authenticationInformation, String envelopeId, String returnPageURL, SignerInformation signer){
        String url = authenticationInformation.baseURL + '/envelopes/' + envelopeId + '/views/recipient';
        String body = '<recipientViewRequest xmlns=\'http://www.docusign.com/restapi\'>'  +
                      '<returnUrl>' + returnPageURL +  '</returnUrl>' +
                      '<authenticationMethod>email</authenticationMethod>' +
                      '<email>' + signer.signerEmail + '</email>' +
                      '<clientUserId>' + signer.recipientId + '</clientUserId>' +
                      '<userName>' + signer.signerName + '</userName>' +
                      '</recipientViewRequest>';
        HttpRequest request = new HttpRequest();
        request.setMethod('POST');
        request.setEndpoint(url);
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/xml');
        request.setHeader('Accept''application/xml');
        request.setHeader('Content-Length', String.valueOf(body.length()));
        if(body.contains('&')){
            body = body.replace('&','&amp;');
        }
        request.setBody(body);
        http h = new http();
        HttpResponse response = new HttpResponse();
        //Send http request
        response = h.send(request);
        String signingUrl;
        Dom.Document doc = response.getBodyDocument();
        for(dom.XmlNode node : doc.getRootElement().getChildElements()) {
            if(node.getName() == 'url') {
                signingUrl = node.getText();
            }
        }
        return new DocumentInformation(envelopeId, nullnullnull, signingUrl);
    }
    /*
     * Method Name: fetchRecipients
     * Description: Method to fetch the recipients
     * @return: Recipients
     * @param: String, AuthenticationInformation
    */
    public static Recipients fetchRecipients(String envelopeId, AuthenticationInformation authenticationInformation){
        String url = authenticationInformation.baseURL + '/envelopes/' + envelopeId + '/recipients?include_tabs=true';
        HttpRequest request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('GET');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Accept''application/json');
        http h = new http();
        HttpResponse response = new HttpResponse();
        response = h.send(request);
        Recipients recipients = (Recipients)JSON.deserialize(response.getBody(), Recipients.class);
        recipients.recipientCount = recipients.signers.size();
        Integer index = 0;
        for(Signer temp : recipients.signers){
            if(temp.status == 'sent' || temp.status == 'delivered'){
                recipients.currentRoutingOrder = index + 1;
                break;
            }else if((index + 1) == recipients.recipientCount){
                recipients.currentRoutingOrder = index + 1;
            }
            index += 1;
        }
        return recipients;
    }
    /*
     * Method Name: resendSigningDoc
     * Description: Method to resend signing document
     * @return: String
     * @param: String
    */
    public static String resendSigningDoc(String envelopeId, String email){
        //============================================================================
        // STEP 1 - Make the Login API call to retrieve your baseUrl and accountId
        //============================================================================
        AuthenticationInformation authenticationInformation = authenticate(docusignURL, authenticationHeader);
        //============================================================================
        // STEP 2 - Signature Request from Template API Call
        //============================================================================
        Recipients recipients = fetchRecipients(envelopeId, authenticationInformation);
        if(recipients == null || recipients.signers.isEmpty()){
            return null;
        }
        Integer currentSignerIndex = recipients.currentRoutingOrder -1;
        String signerInfo = '{"signers": [{"recipientId": "' + recipients.signers[currentSignerIndex].recipientId + '","name": "' +
                            recipients.signers[currentSignerIndex].name + '","email": "' +
                            (email != null && email != '' ? email : recipients.signers[currentSignerIndex].email) + '"}]}';
        String url = authenticationInformation.baseURL + '/envelopes/' + envelopeId + '/recipients?resend_envelope=true';
        HttpRequest request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('PUT');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/json');
        request.setHeader('Accept''application/xml');
        request.setBody(signerInfo);
        http h = new http();
        HttpResponse response = new HttpResponse();
        response = h.send(request);
        return null;
    }
    /*
     * Method Name: getSignedDocument
     * Description: Method to get the signed document
     * @param: String
     * @return: DocumentInformation
    */
    public static DocumentInformation getSignedDocument(String envelopeId, Boolean retreiveDocumentBody){
        //============================================================================
        // STEP 1 - Make the Login API call to retrieve your baseUrl and accountId
        //============================================================================
        AuthenticationInformation authenticationInformation = authenticate(docusignURL, authenticationHeader);
        Date signingDate;
        String signingStatus;
        HttpRequest request = new HttpRequest();
        http httpCallout = new http();
        HttpResponse response = new HttpResponse();
        String url = authenticationInformation.baseURL + '/envelopes/' + envelopeId;
        request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('GET');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/xml');
        request.setHeader('Accept''application/xml');
        httpCallout = new http();
        response = new HttpResponse();
        response = httpCallout.send(request);
        Dom.Document doc = response.getBodyDocument();
        for(Dom.XmlNode node : doc.getRootElement().getChildElements()) {
            if(node.getName() == 'status') {
                signingStatus = node.getText();
            }
            if(node.getName() == 'completedDateTime') {
                if(node.getText() != null){
                    List<String> tempList = node.getText().split('T');
                    if(tempList != null && tempList.size() != 0){
                        tempList = tempList.get(0).split('-');
                        if(tempList != null && tempList.size() > 2){
                            signingDate = Date.parse(tempList.get(1) + '/' + tempList.get(2) + '/' +tempList.get(0));
                        }
                    }
                }
            }
        }
        if(signingStatus == 'completed' && retreiveDocumentBody){
            url = authenticationInformation.baseURL + '/envelopes/' + envelopeId + '/documents/combined';
            request = new HttpRequest();
            request.setEndpoint(url);
            request.setMethod('GET');
            request.setHeader('X-DocuSign-Authentication', authenticationHeader);
            request.setHeader('Content-Type''application/json');
            request.setHeader('Accept''application/pdf');
            httpCallout = new http();
            response = new HttpResponse();
            // sending http request
            response = httpCallout.send(request);
            return new DocumentInformation(envelopeId, response.getBodyAsBlob(), signingDate, signingStatus, null);
        }
        return new DocumentInformation(envelopeId, null, signingDate, signingStatus, null);
    }
    /*
     * Method Name: setDocumentStatus
     * Description: Method to set the document status
     * @param: String, String
     * @return: DocumentInformation
    */
    public static void setDocumentStatus(String envelopeId, String status){
        //============================================================================
        // STEP 1 - Make the Login API call to retrieve your baseUrl and accountId
        //============================================================================
        AuthenticationInformation authenticationInformation = authenticate(docusignURL, authenticationHeader);
        HttpRequest request = new HttpRequest();
        http httpCallout = new http();
        HttpResponse response = new HttpResponse();
        String url = authenticationInformation.baseURL + '/envelopes/' + envelopeId;
        request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('PUT');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/json');
        request.setHeader('Accept''application/xml');
        request.setBody('{"status": "'+ status +'", "voidedReason": "The reason for voiding the envelope"}');
        httpCallout = new http();
        response = new HttpResponse();
        response = httpCallout.send(request);
    }    
    /*
     * Method Name: authenticate
     * Description: Method to authenticate the docusign api
     * @param: String, String
     * @return: AuthenticationInformation
    */
    public static AuthenticationInformation authenticate(String docusignURL, String authenticationHeader){
        String url = docusignURL + '/restapi/v2/login_information';
        String body = '';   // no request body for the login call
        HttpRequest request = new HttpRequest();
        request.setEndpoint(url);
        request.setMethod('GET');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/xml');
        request.setHeader('Accept''application/xml');
        http httpCallout = new http();
        //Creating http response object
        HttpResponse response = new HttpResponse();
        response = httpCallout.send(request);
        Dom.Document doc = response.getBodyDocument();
        String baseUrl = '';
        String accountId = '';
        for(Dom.XmlNode node : doc.getRootElement().getChildElements()) {
            if(node.getName() == 'loginAccounts') {
                for(Dom.XmlNode node1 : node.getChildElements()) {
                    if(node1.getName() == 'loginAccount') {
                        for(Dom.XmlNode node2 : node1.getChildElements()) {
                            if(node2.getName() == 'accountId') {
                                accountId = node2.getText();
                            }
                            if(node2.getName() == 'baseUrl') {
                                baseUrl = node2.getText();
                            }
                        }
                    }
                }
            }
        }
        return new AuthenticationInformation(baseUrl, accountId);
    }
    /*
    * Method Name: getCompletedEnvelopDateMap
    * Description: Method to get complete envelop data map
    * @return: static Map<String, Date>
    * @param: N/A
    */
    public static Map<StringDate> getCompletedEnvelopDateMap(){
        Map<StringDate> completedEnvelopDateMap = new Map<StringDate>();
        //============================================================================
        // STEP 1 - Make the Login API call to retrieve your baseUrl and accountId
        //============================================================================
        AuthenticationInformation authenticationInformation = authenticate(docusignURL, authenticationHeader);
        HttpRequest request = new HttpRequest();
        http httpCallout = new http();
        HttpResponse response = new HttpResponse();
        Date from_date = Date.today().addMonths(-2);
        Date to_date = Date.today().addMonths(1);
        String url = authenticationInformation.baseURL + '/envelopes?from_date=' + from_date.month() + '%2F' + from_date.day() + '%2F' + from_date.year() + '%2000%3A00'
                +'&from_to_status=changed&to_date=' + to_date.month() + '%2F' + to_date.day() + '%2F' + to_date.year() + '%2000%3A00' +
                '&status=Completed';
        request.setEndpoint(url);
        request.setMethod('GET');
        request.setHeader('X-DocuSign-Authentication', authenticationHeader);
        request.setHeader('Content-Type''application/xml');
        request.setHeader('Accept''application/xml');
        response = httpCallout.send(request);
        Dom.Document doc = response.getBodyDocument();
        String tempEnvelopId;
        Date tempSignDate;
        for(dom.XmlNode node : doc.getRootElement().getChildElements()) {
            for(dom.XmlNode childNode : node.getChildElements()) {
                tempEnvelopId = null;
                tempSignDate = null;
                if(childNode.getName() == 'envelope') {
                    for(dom.XmlNode innerNode : childNode.getChildElements()) {
                        if(innerNode.getName() == 'envelopeId') {
                            tempEnvelopId = innerNode.getText();
                        }
                        if(innerNode.getName() == 'statusChangedDateTime') {
                            if(innerNode.getText() != null){
                                List<String> tempList = innerNode.getText().split('T');
                                if(tempList != null && tempList.size() != 0){
                                    tempList = tempList.get(0).split('-');
                                    if(tempList != null && tempList.size() > 2){
                                        tempSignDate = Date.parse(tempList.get(1) + '/' + tempList.get(2) + '/' +tempList.get(0));
                                        if(tempEnvelopId != null && tempSignDate != null){
                                            completedEnvelopDateMap.put(tempEnvelopId, tempSignDate);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        System.debug('>>> response = ' + response);
        System.debug('>>> tempEnvelopId = ' + tempEnvelopId);
        return completedEnvelopDateMap;
    }
    //Wrapper class for the authentication information
    public class AuthenticationInformation{
        public String baseURL;
        public String accountId;
        public AuthenticationInformation(String baseURL, String accountId){
            this.baseURL = baseURL;
            this.accountId = accountId;
        }
    }
    //Wrapper class for the signer information
    public class SignerInformation{
        public String signerName;
        public String signerEmail;
        public Integer recipientId;
        public Integer routingOrder;
        public String signLabel;
        public String signDateLabel;
        public SignerInformation(String signerName, String signerEmail, Integer recipientId, Integer routingOrder, String signLabel, String signDateLabel){
            this.signerName = signerName;
            this.signerEmail = signerEmail;
            this.recipientId = recipientId;
            this.routingOrder = routingOrder;
            this.signLabel = signLabel;
            this.signDateLabel = signDateLabel;
        }
    }
    //Wrapper class for the document information
    public class DocumentInformation{
        public String envelopeId;
        public blob documentData;
        public Date signingDate;
        public String signingStatus;
        public String signingUrl;
        public DocumentInformation(String envelopeId, blob documentData, Date signingDate, String signingStatus, String signingUrl){
            this.envelopeId = envelopeId;
            this.documentData = documentData;
            this.signingDate = signingDate;
            this.signingStatus = signingStatus;
            this.signingUrl = signingUrl;
        }
    }
    //Wrapper class for Recipients
    public class Recipients{
        public List<Signer> signers;
        public Integer currentRoutingOrder;
        public Integer recipientCount;
    }
    //Wrapper class for Signer
    public class Signer{
        public String status;
        public String email;
        public String name;
        public String recipientId;
        public String routingOrder;
        public String signedDateTime;
        public Tab tabs;
    }
    //Wrapper class for tabs
    public class Tab{
        List<SignHereTab> signHereTabs;
    }
    //Wrapper class for signHereTab
    public class SignHereTab{
        public String anchorString;
    }
}



_____________________________________________________________________
2- Controller
global with sharing class EEC_DocusignController {
    public Transaction_Contact__c transactionContactRec     {getset;}
    public Transaction_Contact__c transactionContactRecord  {getset;}
    public String errorMessage                              {getset;}
    public Boolean reloadPage                               {getset;}
    public EEC_DocusignController() {
        String transactionContactId = Apexpages.currentPage().getParameters().get('transactionId');
        errorMessage = '';
        reloadPage = true;
        if(String.isNotBlank(transactionContactId)) {
            transactionContactRecord = [SELECT Id,
                                            First_Name__c,
                                            Last_Name__c,
                                            Date_of_Birth__c,
                                            Envelope_Id__c,
                                            BRC_Consent_Status__c,
                                            BRC_Consent_Signed_Date__c
                                        FROM Transaction_Contact__c
                                        WHERE Id = :transactionContactId];
            transactionContactRec = new Transaction_Contact__c(Id = transactionContactId, First_Name__c = transactionContactRecord.First_Name__c, Last_Name__c = transactionContactRecord.Last_Name__c);
        }
    }
    public void saveTransactionContact() {
        try {
            errorMessage = '';
            Date minimumDate = Date.newInstance(1900,01,01);
            if(transactionContactRec.Date_of_Birth__c!=null){
                if(transactionContactRec.Date_of_Birth__c < minimumDate || System.today() < transactionContactRec.Date_of_Birth__c.addYears(15)){
                    transactionContactRec.Date_of_Birth__c.addError('Applicant age should be greater than 15 years and Birth date should be greater than');
                    reloadPage = false;
                }
            }
            if(!(transactionContactRec.Current_Residential_Zip__c != null && transactionContactRec.Current_Residential_Zip__c.isNumeric() && transactionContactRec.Current_Residential_Zip__c.length() == 5 )){
                transactionContactRec.Current_Residential_Zip__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Mailing_Zip__c != null && transactionContactRec.Mailing_Zip__c.isNumeric() && transactionContactRec.Mailing_Zip__c.length() == 5 )){
                transactionContactRec.Mailing_Zip__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_1__c != null && transactionContactRec.Out_of_state_Zip_1__c.isNumeric() && transactionContactRec.Out_of_state_Zip_1__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_1__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_2__c != null && transactionContactRec.Out_of_state_Zip_2__c.isNumeric() && transactionContactRec.Out_of_state_Zip_2__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_2__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_3__c != null && transactionContactRec.Out_of_state_Zip_3__c.isNumeric() && transactionContactRec.Out_of_state_Zip_3__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_3__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_4__c != null && transactionContactRec.Out_of_state_Zip_4__c.isNumeric() && transactionContactRec.Out_of_state_Zip_4__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_4__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_5__c != null && transactionContactRec.Out_of_state_Zip_5__c.isNumeric() && transactionContactRec.Out_of_state_Zip_5__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_5__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_6__c != null && transactionContactRec.Out_of_state_Zip_6__c.isNumeric() && transactionContactRec.Out_of_state_Zip_6__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_6__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_7__c != null && transactionContactRec.Out_of_state_Zip_7__c.isNumeric() && transactionContactRec.Out_of_state_Zip_7__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_7__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_8__c != null && transactionContactRec.Out_of_state_Zip_8__c.isNumeric() && transactionContactRec.Out_of_state_Zip_8__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_8__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(!(transactionContactRec.Out_of_state_Zip_9__c != null && transactionContactRec.Out_of_state_Zip_9__c.isNumeric() && transactionContactRec.Out_of_state_Zip_9__c.length() == 5 )){
                transactionContactRec.Out_of_state_Zip_9__c.addError('Zip code must be of 5 digits.');
                reloadPage = false;
            }
            if(reloadPage) {
                upsert transactionContactRec;
            }
        } catch (Exception except) {
            errorMessage = except.getMessage();
        }
    }
    /*
    * Method Name: getSiginingUrl
    * Description: getting signing URL
    * @param: String transactionId
    * @param: String pdfPageName
    * @return: String
    */ 
    @RemoteAction
    global static String getSiginingUrl(String transactionId){
        String domainURL = URL.getSalesforceBaseUrl().toExternalForm();
        Pagereference returnPage = Page.EEC_DocusignPage;
        returnPage.getParameters().put('transactionId', transactionId);
        Pagereference pdfPage = Page.EEC_DocusignPDF;
        pdfPage.getParameters().put('transactionId', transactionId);
        return EEC_DocusignServiceUtility.sendDocumentForSigning(transactionId, returnPage.getUrl(), pdfPage);
    }
    @RemoteAction
    global static String getSignedDocumentStatus(String isSigned, String transactionId) {
        if(String.isNotBlank(transactionId)) {
            Transaction_Contact__c transactionContact = [SELECT Id,
                                                            Envelope_Id__c,
                                                            BRC_Consent_Status__c,
                                                            BRC_Consent_Signed_Date__c,
                                                            First_Name__c,
                                                            Last_Name__c,
                                                            Email__c
                                                        FROM Transaction_Contact__c
                                                        WHERE Id =: transactionId];
            if(transactionContact.BRC_Consent_Signed_Date__c == null && transactionContact.Envelope_Id__c != null && isSigned == 'signing_complete'){
                EEC_DocusignServiceUtility.DocumentInformation documentInformation = EEC_DocusignServiceUtility.getSignedDocument(transactionContact.Envelope_Id__c, true);
                Attachment attachment = new Attachment(ParentId = transactionId, Body = documentInformation.documentData,
                        Name = 'Consent licensee - ' + Date.today(),
                        ContentType = 'application/pdf');
                insert attachment;
                transactionContact.BRC_Consent_Signed_Date__c = documentInformation.signingDate;
                transactionContact.BRC_Consent_Status__c = documentInformation.signingStatus;
                update transactionContact;
            } else if(transactionContact.Envelope_Id__c != null && transactionContact.BRC_Consent_Status__c != 'Completed') {
                EEC_DocusignServiceUtility.DocumentInformation documentInformation = EEC_DocusignServiceUtility.getSignedDocument(transactionContact.Envelope_Id__c, false);
                if(documentInformation.signingStatus != 'Completed') {
                    Pagereference returnPage = Page.EEC_DocusignPage;
                    returnPage.getParameters().put('transactionId', transactionId);
                    String signingURL = EEC_DocusignServiceUtility.getSigningURL(transactionContact.Envelope_Id__c, returnPage.getUrl(), 
                                                                                transactionContact.First_Name__c + ' ' + transactionContact.Last_Name__c,
                                                                                transactionContact.Email__c, 1);
                    return signingURL;
                }
            }
        }
        return null;
        //system.debug(Docusign_Sevice_Utility.getCompeltedEnvelopDateMap());
    }
    public void mailingAddressSameAsResidentialAddress() {
        if(transactionContactRec.Residential_Copy_Over_Mailing_Address__c) {
            transactionContactRec.Mailing_Address_Line_1__c = transactionContactRec.Current_Residential_Address_Line_1__c;
            transactionContactRec.Mailing_Address_Line_2__c = transactionContactRec.Current_Residential_Address_Line_2__c;
            transactionContactRec.Mailing_City__c = transactionContactRec.Current_Residential_City__c;
            transactionContactRec.Mailing_State__c = transactionContactRec.Current_Residential_State__c;
            transactionContactRec.Mailing_Zip__c = transactionContactRec.Current_Residential_Zip__c;
        } else {
            transactionContactRec.Mailing_Address_Line_1__c = '';
            transactionContactRec.Mailing_Address_Line_2__c = '';
            transactionContactRec.Mailing_City__c = '';
            transactionContactRec.Mailing_State__c = '';
            transactionContactRec.Mailing_Zip__c = '';
        }
    }
}