com.intuit.qboecoui.email.SalesFormEmail.java Source code

Java tutorial

Introduction

Here is the source code for com.intuit.qboecoui.email.SalesFormEmail.java

Source

package com.intuit.qboecoui.email;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.ActivityNotFoundException;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnCancelListener;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.res.Configuration;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.volley.Response.ErrorListener;
import com.android.volley.Response.Listener;
import com.android.volley.VolleyError;
import com.intuit.elves.app.BaseApplicationModule;
import com.intuit.elves.log.CustomLog;
import com.intuit.elves.network.CustomError;
import com.intuit.elves.network.NetworkUtil;
import com.intuit.qboecocomp.datasync.ISyncConstants;
import com.intuit.qboecocomp.datasync.entity.QBODocumentLinkEntity;
import com.intuit.qboecocomp.datasync.entity.SalesFormsEmailEntity;
import com.intuit.qboecocomp.datasync.entity.SalesFormsEmailEntity.TXN_TYPE;
import com.intuit.qboecocomp.json.request.V3Operation;
import com.intuit.qboecocomp.network.AddEmailRequest;
import com.intuit.qboecocomp.network.GetCompanyPrefDataRequest;
import com.intuit.qboecocomp.network.UpdateSFMPreferenceAndSendEmailRequest;
import com.intuit.qboecocomp.qbo.attachable.model.AttachableDataAccessor;
import com.intuit.qboecocomp.qbo.common.data.AttachableAssociation;
import com.intuit.qboecocomp.qbo.common.model.DataHelper;
import com.intuit.qboecocomp.qbo.companyinfo.model.CompanyInfoDetails;
import com.intuit.qboecocomp.qbo.companyinfo.model.QBCompanyInfoDataAccessor;
import com.intuit.qboecocomp.qbo.estimate.model.EstimateManager;
import com.intuit.qboecocomp.qbo.invoice.model.InvoiceManager;
import com.intuit.qboecocomp.qbo.prefs.data.Preference;
import com.intuit.qboecocomp.qbo.salesreceipt.model.SalesReceiptManager;
import com.intuit.qboecocomp.qbo.transaction.model.ContactData;
import com.intuit.qboecocomp.qbo.transaction.model.TransactionData;
import com.intuit.qboecocomp.qbo.transaction.model.TransactionManager;
import com.intuit.qboecocomp.tracking.TrackConstants;
import com.intuit.qboecocomp.util.FormattingUtility;
import com.intuit.qboecocomp.util.Util;
import com.intuit.qboecocore.app.QBOApplicationModule;
import com.intuit.qboecocore.auth.response.Response;
import com.intuit.qboecocore.common.BaseAppPreferences;
import com.intuit.qboecocore.exception.PSQBOServiceErrorCodes;
import com.intuit.qboecocore.exception.QBException;
import com.intuit.qboecocore.json.V3SalesFormEmailJson;
import com.intuit.qboecocore.network.StringResponse;
import com.intuit.qboecocore.network.exception.IErrorCodes;
import com.intuit.qboecocore.network.response.IResponseCode;
import com.intuit.qboecoui.R;
import com.intuit.qboecoui.common.AppPreferences;
import com.intuit.qboecoui.common.aidl.IActivityCallback;
import com.intuit.qboecoui.common.aidl.IServiceCallback;
import com.intuit.qboecoui.common.ui.BaseFragment;
import com.intuit.qboecoui.common.ui.BaseSinglePaneActivity;
import com.intuit.qboecoui.common.ui.dialog.ErrorDialog;
import com.intuit.qboecoui.paymentshub.utils.CreditCardTypeUtils;
import com.intuit.qboecoui.qbo.preview.PreviewResponseHandler;
import com.intuit.qboecoui.qbo.preview.PreviewService;
import com.intuit.qboecoui.tracking.QBMTrackConstants;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;

import pdftron.Common.PDFNetException;
import pdftron.PDF.PDFDoc;
import pdftron.PDF.PDFNet;
import pdftron.PDF.PDFViewCtrl;

// TODO : Re-factor this class for better maintainability. (Kbhalla sept 5 2014)
/**
 * This activity handles the sales form email for the following sales
 * transactions: 1. Estimates 2. Invoices 3. Sales Receipts
 *
 * The generic email functionality includes:
 *    1. Open the activity with controls configured for emailing transaction
 *       1.1.   Load the message defaults for subject and body from company preferences
 *       1.2.   Load the email address(es) received as part of the transaction payload
 *       1.3.   Customize the form UI based on the transaction being emailed and the company preferences
 *
 *    2.   Sending email
 *       2.1    Validating form fields
 *          2.1.1   Email addresses (single and multiple)
 *          2.1.2   subject and body content
 *       2.2      Checks company preferences for the
 *
 *    3. Preview transaction before sending the email on the form
 *       3.1      Use PDF Tron to render the pdf in same form. (TODO P1 - Change this to android PDF renderer available from minSDK 21 lollipop)
 *         3.1.1      Support the zoom and scroll for the rendered pdf in control
 *         3.1.2      Launch the external PDF viewer when the pdf is clicked.
 *
 *
 *
 * @author kbhalla
 *
 */
public class SalesFormEmail extends BaseSinglePaneActivity
        implements OnClickListener, Listener<StringResponse>, ErrorListener {

    private final static String TAG = "SalesFormEmail";

    //    Projection for reading the preference table and get the required preferences
    private static final String sfm_preference_projections[] = new String[] {
            Preference.ETRANSACTION_ENABLED_STATUS, Preference.ETRANSACTION_PAYMENT_ENABLED,
            Preference.ETRANSACTION_ATTACH_PDF, Preference.INVOICE_MESSAGE, Preference.INVOICE_SUBJECT,
            Preference.SALESRECEIPT_MESSAGE, Preference.SALESRECEIPT_SUBJECT, Preference.ESTIMATE_MESSAGE,
            Preference.ESTIMATE_SUBJECT };

    private final static String SUPPORTED_EMAIL_SEPARATOR = ",";
    private final static int SUPPORTED_EMAIL_BODY_CONTENT_SIZE = 4000;
    private final static double US_LETTER_HEIGHT_WIDTH_RATIO = 1.29;

    private PDFViewCtrl mPDFViewCtrl; //   UI control to load and render the pdf into.
    private LinearLayout mPdfLoadingMessage; //   control to show the pdf loading message

    // mCurrentCommandRequest is used to track which service request is currently being processed.
    private int mCurrentCommandRequest = 0;

    //   hasPreviewLaunched is used to ensure that only one instance of external pdf viewer is launched.
    private static boolean hasPreviewLaunched = false;

    @Override
    public void onBackPressed() {
        //    Unbind the preview service when the back button is pressed.
        if (mPreviewHandler != null) {
            ((PreviewResponseHandler) mPreviewHandler).onFinish();
        }
        super.onBackPressed();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        final int titleResId = R.string.send_email_title;
        setTitle(titleResId);

        // Extract URI of the transaction that initiated the Sales form email.
        mUri = getIntent().getData();

        // set the transaction type and transaction manager objects.
        setTransactionType(getIntent().getExtras().getInt(SalesFormsEmailEntity.TXN_TYPE_KEY));

        // Create a object of the JSON entity. this will be used to hold the
        // form data and create the payload for the "Send" endpoint.
        mSalesFormEmailJson = new V3SalesFormEmailJson();

        // Initialize the library with the license key.
        try {
            PDFNet.initialize(this, R.raw.pdfnet,
                    "Intuit Inc.(intuit.com):OEM:QuickBooks Online[QBO]::LMIA:AMS(20150103):3E7723C11F273AD0330FAD7860611FA5C7581A63CB22056B1CBF0EF024DABEF5C7");
        } catch (PDFNetException e) {
            CustomLog.logDebug(TAG, "onCreate - initialize PDFNet");
        }

        // Inflate the view and get a reference to PDFViewCtrl
        setContentView(R.layout.v3email_layout);

        // setting up action bar
        getActivityHelper().setupActionBar(mTitle, false, false, true);
        getActivityHelper().showActionBar();

        // load the email preferences from data base.
        loadEmailMessagePrefsFromDB(this.getApplicationContext());
        // Customize the send email form based on the transaction type and
        // company file preferences
        customizeSalesFormEmailForm();
        BaseApplicationModule.getTrackingModule().trackPage(QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME);
        //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME);

        // Load the default values for the sales form email form, from
        // preferences and transaction entity.
        loadDefaultSalesFormEmailFormData();
        // setting up action bar
        getActivityHelper().setupActionBar(mTitle, false, false, true);
        getActivityHelper().showActionBar();
        CustomLog.logDebug(TAG, "SalesFormEmail: onCreate");

        mPDFViewCtrl = (PDFViewCtrl) findViewById(R.id.pdfviewctrl);
        mPdfLoadingMessage = (LinearLayout) findViewById(R.id.pdf_loading);

        mPDFViewCtrl.setVisibility(View.GONE);
        mPdfLoadingMessage.setVisibility(View.VISIBLE);

        // SalesFormEmail.SFM_Flow_tracking = "";

        preview(mUri);
    }

    /*
     * This adds items to the menu section that is showing at the bottom of the
     * screen.
     *
     * @see
     * com.intuit.qboecoui.quickbooks.ui.QuickBooksActivity#onCreateOptionsMenu(android
     * .view.Menu)
     */
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        final MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.sales_form_email_details_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    protected BaseFragment onCreatePane() {
        // TODO Auto-generated method stub
        return null;
    }

    /**
     * This method displays the dialog asking the user to turn on the attach pdf
     * preference and send the email.
     */
    public void attachPDFPreferencePopup() {
        new AlertDialog.Builder(this).setMessage(R.string.sfm_turn_on_attach_pdf_preference)
                .setTitle(R.string.sfm_turn_on_attach_pdf_preference_title)
                .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        BaseApplicationModule.getTrackingModule().trackLink(
                                QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME,
                                QBMTrackConstants.TRANSACTION_SAVE_YES_ACTION);
                        handleUpdatePreference();
                    }
                }).setNeutralButton(R.string.no, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        // User does not want to set the preference. We will not show the OTM again.
                        AppPreferences.setBooleanPreference(
                                QBOApplicationModule.getInstance().getApplicationContext(), null,
                                AppPreferences.KEY_ATTACH_PDF_PREFERENCE_OTM_SHOW, false);
                        BaseApplicationModule.getTrackingModule().trackLink(
                                QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME,
                                QBMTrackConstants.TRANSACTION_SAVE_NO_ACTION);
                        issueSendEmailRequest();

                    }
                }).show();
    }

    /**
     *    This method prepares the command to update the company preference and send the email.
     * @return
     */
    private boolean handleUpdatePreference() {

        //    If there is no error in form data send the request.
        JSONObject jsonObj = new JSONObject();
        try {
            jsonObj.put(V3Operation.SEND, mSalesFormEmailJson.toSerialize());
        } catch (JSONException e1) {
            CustomLog.logError(TAG, e1, "SalesFormEmail: problem deteceted while serializing the send payload.");
            return false;
        }

        String jsonPayload = "";
        try {
            jsonPayload = (jsonObj.get(V3Operation.SEND)).toString();
        } catch (JSONException exception) {
            CustomLog.logError(TAG, exception, "SalesFormEmail: Error retrieving the payload");
            return false;
        }

        // handle update of the attach pdf preference.
        final ContentValues pContentValues = new ContentValues(2);
        pContentValues.clear();
        pContentValues.put(Preference._ID, 1);
        pContentValues.put(Preference.ETRANSACTION_ATTACH_PDF, "true");
        mCurrentCommandRequest = ISyncConstants.FLAG_EDIT_PREF_AND_SEND_MAIL;
        Uri prefUri = getApplicationContext().getContentResolver().insert(Preference.CONTENT_URI, pContentValues);
        UpdateSFMPreferenceAndSendEmailRequest updateRequest = UpdateSFMPreferenceAndSendEmailRequest.createRequest(
                BaseApplicationModule.getNetworkModule(), this, ISyncConstants.FLAG_EDIT_PREF_AND_SEND_MAIL,
                prefUri, mUri, jsonPayload, mTransactionType, this, this);
        updateRequest.setTag(this);
        // TODO P1 : check this code for case when the update preference fails / passes.
        BaseApplicationModule.getNetworkModule().dispatchRequest(updateRequest);

        try {
            // We shoud stop the pdf preview service here
            this.stopService(new Intent(this, PreviewService.class));
            ((PreviewResponseHandler) mPreviewHandler).onFinish();
        } catch (SecurityException ex) {
            // do nothing
        }

        // track the click of send button
        //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SALES_FORM_EMAIL_SENT );
        BaseApplicationModule.getTrackingModule().trackLink(QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME,
                QBMTrackConstants.SALES_FORM_EMAIL_SENT_WITH_PREF_UPDATE);
        startProgressBar(getString(R.string.sales_form_email_sending_email_text));
        return true;
    }

    /**
     *    This method determines if the OTM seeking the user to turn on the PDF attach preference is to be handled.
     *
     *    @return true when the pop-up is displayed / handled
     */
    private boolean handleAttachPDF_OTM() {
        boolean handleAttachPDFOTM = false;
        // Show the pop-up
        /*
         *    check 1. In preference if the pop-up has been shown before? if not
         *    check 2. Is the company neo enabled? and eTransactionEnabledStatus is enabled and the attachPDFFlag is turned off. If true
         *    Show the pop-up and flag it in the settings ...
         */
        final boolean showOTM = AppPreferences.getBooleanPreference(
                QBOApplicationModule.getInstance().getApplicationContext(), null,
                AppPreferences.KEY_ATTACH_PDF_PREFERENCE_OTM_SHOW, true);

        if (showOTM && mTransactionType == TXN_TYPE.INVOICE && Util.isNeoEnabled()
                && SalesFormEmail.ETransactionEnabledStatus_ENABLED.equalsIgnoreCase(mETransactionEnabledStatus)
                && !mETransactionAttachPDF) {
            // Show the popup
            handleAttachPDFOTM = true;
            attachPDFPreferencePopup();
        }

        return handleAttachPDFOTM;
    }

    /*
     * Handle Menu clicks for this screen.
     *
     * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem)
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int id = item.getItemId();
        if (id == R.id.sales_form_email_send) {

            retrieveSalesFormEmailData(mSalesFormEmailJson);

            // Check if there is no internet connectivity.
            if (!NetworkUtil.checkInternetConnection(this)) {
                new ErrorDialog(this, getString(R.string.login_network_error),
                        getString(R.string.error_title_unable_to_connect));
                return false;
            }

            // Validate form data and handle that.
            String errorString = validateFromData(mSalesFormEmailJson);
            if (!TextUtils.isEmpty(errorString)) {
                errorString = getString(R.string.sales_form_email_error_header_message) + errorString;
                new ErrorDialog(this, errorString, getString(R.string.sales_form_email_error_title));
            } else {
                if (!handleAttachPDF_OTM()) {
                    return issueSendEmailRequest();
                }
            }
        } else {
            return super.onOptionsItemSelected(item);
        }
        return true;
    }

    private boolean issueSendEmailRequest() {
        if (!prepareAndSendTheRequest()) {
            stopProgressBar();
            return false; // in case of error in sending the request we
            // log the error and return false to the
            // caller.
            // TODO P1 - check where is this flow heading to.

        } else {
            // Form data is validated and request is sent. Start the
            // progress bar.
            startProgressBar(getString(R.string.sales_form_email_sending_email_text));
            return true;
        }
    }

    public void onCallback(int op, int responseCode, String pMessage) {
        CustomLog.logDebug(TAG, "SalesFormEmail : onCallback : responseCode is " + responseCode);
        mHandler.sendMessage(mHandler.obtainMessage(op, responseCode, 0, pMessage));
    }

    // -----------------------------
    // Private members of the class
    // -----------------------------

    private Uri mUri = null; // holds the URI of the transaction we want to send
    // email of.
    private V3SalesFormEmailJson mSalesFormEmailJson = null; // JSON data
    // container for
    // email data.
    private ProgressDialog mProgressDialog;

    private TXN_TYPE mTransactionType; // This enum holds the transaction type
    // for which the email needs to be sent.
    private TransactionManager mTransactionManager; // holds the reference of
    // the manager object of the
    // respective transaction.

    /**
     * ETransactionEnabledStatus Specifies if ETransaction (eInvoicing) is
     * enabled or not. Supported values are Enabled, NotApplicable
     */
    private String mETransactionEnabledStatus = "";

    /**
     * ETransactionAttachPDF Attach Sales PDF with eTransaction email When as
     * Input, processed only when "ETransactionEnabledStatusEnum" is Enabled.
     * Otherwise ignored.
     */
    private boolean mETransactionAttachPDF = false;

    /**
     * ETransactionPaymentEnabled Will be true if MAS subscription is Approved
     * and region is US
     */
    private boolean mETransactionPaymentEnabled = false;

    public static String ETransactionEnabledStatus_ENABLED = "Enabled";

    /**
     * This method sets the mTransactionType member to current sales form
     * transaction which we need to send email for.
     */
    private void setTransactionType(int aTransactionCode) {
        if (aTransactionCode == TXN_TYPE.ESTIMATE.getValue()) {
            mTransactionType = TXN_TYPE.ESTIMATE;
            mTransactionManager = new EstimateManager();
        } else if (aTransactionCode == TXN_TYPE.SALES_RECEIPT.getValue()) {
            mTransactionType = TXN_TYPE.SALES_RECEIPT;
            mTransactionManager = new SalesReceiptManager();
        } else {
            mTransactionType = TXN_TYPE.INVOICE;
            mTransactionManager = new InvoiceManager();
        }
    }

    /**
     * This method customizes the sales form email form based on the transaction
     * type and company file preferences. This determines if preferences for
     * online payment will be displayed or not.
     */
    private void customizeSalesFormEmailForm() {

        if (mTransactionType == TXN_TYPE.INVOICE) {
            // We will show the online payment options only if the company file
            // is a Harmony file.
            // EInvoicing is enabled and MAS subscription is paid.
            if (Util.isNeoEnabled()) {
                LinearLayout onlinePaymentPreferencesContainer = (LinearLayout) findViewById(
                        R.id.pref_online_payment_container);
                if (onlinePaymentPreferencesContainer != null && SalesFormEmail.ETransactionEnabledStatus_ENABLED
                        .equalsIgnoreCase(mETransactionEnabledStatus) && mETransactionPaymentEnabled) {
                    // Show these preferences
                    onlinePaymentPreferencesContainer.setVisibility(View.VISIBLE);
                }
                if (Util.shouldBankTransferOptionBeShown()) {
                    onlinePaymentPreferencesContainer.findViewById(R.id.pref_bank_transfer)
                            .setVisibility(View.VISIBLE);
                } else {
                    onlinePaymentPreferencesContainer.findViewById(R.id.pref_bank_transfer)
                            .setVisibility(View.GONE);
                }
            }
        }
    }

    private final Handler mHandler = new Handler() {
        // Process the message generated at the time of QBDataSyncService
        // processing
        @Override
        public void handleMessage(Message msg) {
            handleDataSyncResponse(msg);
        }
    };

    /**
     * This method prepares and sends the sales form email request to the v3 end
     * point.
     */
    private boolean prepareAndSendTheRequest() {
        // If there is no error in form data send the request.
        JSONObject jsonObj = new JSONObject();
        try {
            jsonObj.put(V3Operation.SEND, mSalesFormEmailJson.toSerialize());
        } catch (JSONException e1) {
            CustomLog.logError(TAG, e1, "SalesFormEmail: problem deteceted while serializing the send payload.");
            return false;
        }

        String jsonPayload = "";
        try {
            jsonPayload = (jsonObj.get(V3Operation.SEND)).toString();
        } catch (JSONException exception) {
            CustomLog.logError(TAG, exception, "SalesFormEmail: Error retrieving the payload");
            return false;
        }

        mCurrentCommandRequest = ISyncConstants.FLAG_ADD_EMAIL;
        AddEmailRequest request = AddEmailRequest.createRequest(BaseApplicationModule.getNetworkModule(), this,
                ISyncConstants.FLAG_ADD_EMAIL, mUri, jsonPayload, mTransactionType, this, this);
        request.setTag(this);
        BaseApplicationModule.getNetworkModule().dispatchRequest(request);

        try {
            // We should stop the pdf preview service here as we are sending the request for sending email
            this.stopService(new Intent(this, PreviewService.class));
            ((PreviewResponseHandler) mPreviewHandler).onFinish();
        } catch (SecurityException ex) {
            // do nothing
            /*
               This function will throw {@link SecurityException} if you do not
               *    have permission to stop the given service.
             */
        }

        // track the click of send button
        //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SALES_FORM_EMAIL_SENT );
        BaseApplicationModule.getTrackingModule().trackLink(QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME,
                QBMTrackConstants.SALES_FORM_EMAIL_SENT);
        return true;
    }

    /**
     * This method validates the Sales form email data.
     *
     * @param salesFormEmailJson
     * @return
     */
    private String validateFromData(V3SalesFormEmailJson salesFormEmailJson) {
        String returnValue = "";

        if (TextUtils.isEmpty(salesFormEmailJson.EmailMessage.Subject)) {
            returnValue += getString(R.string.sales_form_email_error_missing_subject);
        }

        if (salesFormEmailJson.EmailMessage.Message.length() > SUPPORTED_EMAIL_BODY_CONTENT_SIZE) {
            returnValue += getString(R.string.sales_form_email_error_huge_email_content);
        }

        if (TextUtils.isEmpty(salesFormEmailJson.DeliveryAddress.Address)) {
            returnValue += getString(R.string.sales_form_email_error_missing_email_id);
        } else {
            salesFormEmailJson.DeliveryAddress.Address = salesFormEmailJson.DeliveryAddress.Address.replace(";",
                    SUPPORTED_EMAIL_SEPARATOR);
            // In case of multiple emails split them and validate each one.
            final String emailAddressesString = salesFormEmailJson.DeliveryAddress.Address;
            String[] emailAddressesTokenized = emailAddressesString.split(SUPPORTED_EMAIL_SEPARATOR);

            if (!Util.validateMultipleEmails(emailAddressesTokenized)) {
                returnValue += getString(R.string.sales_form_email_error_invalid_email_id);
            } else {
                String validatedEmailAddresses = "";
                for (String anEmailAddress : emailAddressesTokenized) {
                    if (anEmailAddress != null && !TextUtils.isEmpty(anEmailAddress.trim())) {
                        validatedEmailAddresses += anEmailAddress.trim() + SUPPORTED_EMAIL_SEPARATOR;
                    }
                }
                // remove the trailing "," from validated email addresses
                if (!TextUtils.isEmpty(validatedEmailAddresses)) {
                    validatedEmailAddresses = validatedEmailAddresses.substring(0,
                            validatedEmailAddresses.lastIndexOf(SUPPORTED_EMAIL_SEPARATOR));
                }
                salesFormEmailJson.DeliveryAddress.Address = validatedEmailAddresses;
            }
        }

        return returnValue;
    }

    /**
     * This method fetches the data from the form and populates the
     * V3SalesFormEmailJson object.
     *
     * @param salesFormEmailJson
     *            Return parameter that will be loaded with form data.
     */
    private void retrieveSalesFormEmailData(V3SalesFormEmailJson salesFormEmailJson) {
        final EditText emailReceiver = (EditText) findViewById(R.id.email_receiver);
        if (null != emailReceiver) {
            salesFormEmailJson.DeliveryAddress.Address = emailReceiver.getText().toString();
        }

        final EditText emailSubject = (EditText) findViewById(R.id.email_subject);
        if (null != emailSubject) {
            salesFormEmailJson.EmailMessage.Subject = emailSubject.getText().toString();
        }

        final EditText emailBody = (EditText) findViewById(R.id.email_body);
        if (null != emailBody) {
            salesFormEmailJson.EmailMessage.Message = emailBody.getText().toString();
        }

        // The online payment preferences picked up from the form to be sent in
        // the JSON request.
        final CompoundButton switchBankTransfer = (CompoundButton) findViewById(R.id.switch_bank_transfer);
        final CompoundButton switchCreditCard = (CompoundButton) findViewById(R.id.switch_credit_card);
        salesFormEmailJson.AllowOnlineACHPayment = Boolean.toString(switchBankTransfer.isChecked());
        salesFormEmailJson.AllowOnlineCreditCardPayment = Boolean.toString(switchCreditCard.isChecked());
    }

    /**
     * This method is used for loading any global preferences saved in the pref
     * table.
     */
    private void loadEmailMessagePrefsFromDB(Context pContext) {
        Cursor cursor = null;
        try {
            cursor = pContext.getContentResolver().query(Preference.CONTENT_URI, sfm_preference_projections, null,
                    null, null);
            if (cursor != null && cursor.moveToNext()) {
                mETransactionEnabledStatus = cursor.getString(0);
                mETransactionPaymentEnabled = (cursor.getString(1).equalsIgnoreCase("true") ? true : false);
                mETransactionAttachPDF = (cursor.getString(2).equalsIgnoreCase("true") ? true : false);

                final String invoiceMessage = cursor.getString(3);
                final String invoiceSubject = cursor.getString(4);
                final String salesReceiptMessage = cursor.getString(5);
                final String salesReceiptSubject = cursor.getString(6);
                final String estimateMessage = cursor.getString(7);
                final String estimateSubject = cursor.getString(8);

                if (mTransactionType == TXN_TYPE.INVOICE) {
                    mSalesFormEmailJson.EmailMessage.Subject = invoiceSubject;
                    mSalesFormEmailJson.EmailMessage.Message = invoiceMessage;
                } else if (mTransactionType == TXN_TYPE.ESTIMATE) {
                    mSalesFormEmailJson.EmailMessage.Subject = estimateSubject;
                    mSalesFormEmailJson.EmailMessage.Message = estimateMessage;
                } else if (mTransactionType == TXN_TYPE.SALES_RECEIPT) {
                    mSalesFormEmailJson.EmailMessage.Subject = salesReceiptSubject;
                    mSalesFormEmailJson.EmailMessage.Message = salesReceiptMessage;
                }
            }
        } catch (final Exception ex) {
            CustomLog.logError(TAG, ex, "Error reading email preferences from database");
            // any error in reading/setting prefs should take user out of the
            // app
            throw new QBException(IErrorCodes.ERROR_READING_CURRENCY_FROM_DB);
        } finally {
            if (cursor != null) {
                cursor.close();
                cursor = null;
            }
        }
    }

    /**
     * This method populates the form with following default data: 1. Sender's
     * address from the transaction object. 2. Subject and body of the email
     * from sales form preferences for the specific transaction. 3. Sync token
     * from the transaction.
     *
     */
    private void loadDefaultSalesFormEmailFormData() {
        if (mUri != null) {
            mTransactionManager.retrieveTransactionDetails(mUri);
        }

        TransactionData txnData = mTransactionManager.getTxnData();
        mSalesFormEmailJson.SyncToken = txnData.syncToken;

        //   TODO P2 Check what use case is this? and document this.
        if (mTransactionManager instanceof SalesReceiptManager) {
            SalesReceiptManager srManager = (SalesReceiptManager) mTransactionManager;
            if (srManager.isProcessedPayment()) {
                StringBuilder sb = new StringBuilder();
                sb.append(QBOApplicationModule.getInstance().getApplicationContext().getResources()
                        .getString(R.string.sales_form_email_payment_summary));

                String str = srManager.getTxnData().currency;
                double dbl = srManager.getTotal();
                if (str != null) {
                    str = FormattingUtility.formatCurrency(dbl, str);
                } else {
                    str = FormattingUtility.formatCurrency(dbl);
                }
                sb.append(String.format(QBOApplicationModule.getInstance().getApplicationContext().getResources()
                        .getString(R.string.sales_form_email_amount), str));

                if (srManager.getDateCalendar() != null) {
                    long txnDate = srManager.getDateCalendar().getTimeInMillis();
                    if (txnDate > 0) {
                        str = FormattingUtility.formatDate(new Date(txnDate));
                    }
                    sb.append(String.format("%s %s\n", getString(R.string.date_title), str));
                }
                ContactData contact = srManager.getContact();
                if (contact != null) {
                    sb.append(String.format(QBOApplicationModule.getInstance().getApplicationContext()
                            .getResources().getString(R.string.sales_form_email_paid_by), contact.name));
                }
                CompanyInfoDetails companyInfo = QBCompanyInfoDataAccessor.retrieveCompanyInfo();
                String companyName = companyInfo.legalname != null ? companyInfo.legalname
                        : companyInfo.companyname;
                sb.append(String.format(QBOApplicationModule.getInstance().getApplicationContext().getResources()
                        .getString(R.string.sales_form_email_paid_to), companyName));
                if (companyInfo.legal_addr_city != null && companyInfo.legal_addr_subcode != null) {
                    sb.append(
                            String.format("%s, %s\n", companyInfo.legal_addr_city, companyInfo.legal_addr_subcode));
                }

                str = CreditCardTypeUtils.parseLastFourDigits(srManager.getObfuscatedCardNumber());
                sb.append(String.format(QBOApplicationModule.getInstance().getApplicationContext().getResources()
                        .getString(R.string.sales_form_email_card), str));

                sb.append(String.format("%s: %s", getString(R.string.processed_payment_auth),
                        srManager.getPaymentAuthCode()));
                mSalesFormEmailJson.EmailMessage.Message = mSalesFormEmailJson.EmailMessage.Message
                        .concat(sb.toString());
            }
        }

        // Get the count of attachments
        int countOfAttachments = 0;
        try {
            countOfAttachments = AttachableDataAccessor.getCountOfAttachments(Long.toString(txnData.id),
                    AttachableAssociation.INCLUDE_ON_SEND_URI);
        } catch (QBException QBe) {
            CustomLog.logDebug(TAG, "SalesFormEmail : " + QBe.getMessage());
        }

        final TextView attachmentCount = (TextView) findViewById(R.id.attachment_count);
        if (attachmentCount != null) {
            if (countOfAttachments == 0) {
                final LinearLayout attachmentContainer = (LinearLayout) findViewById(
                        R.id.attachment_count_container);
                if (attachmentContainer != null) {
                    attachmentContainer.setVisibility(View.GONE);
                }
            } else if (countOfAttachments == 1) {
                attachmentCount.setText(getString(R.string.sales_form_email_attachment_text_1));
            } else {
                attachmentCount
                        .setText(String.format(getString(R.string.sales_form_email_attachment_text_morethan1),
                                Integer.toString(countOfAttachments)));
            }
        }

        final EditText emailReceiver = (EditText) findViewById(R.id.email_receiver);
        if (emailReceiver != null) {
            if (!TextUtils.isEmpty(txnData.mBill_email)) {
                emailReceiver.setText(txnData.mBill_email);
            } else if (txnData != null && txnData.mContact != null
                    && !TextUtils.isEmpty(txnData.mContact.externalId)) {
                // Whenever the customer on the sales transaction is changed we will be changing the email address associated with the sales transaction.
                final String[] customerEmail = DataHelper.retrieveEmailAddress(
                        QBOApplicationModule.getInstance().getApplicationContext(), txnData.mContact.externalId);
                if (customerEmail != null && customerEmail.length > 0) {
                    emailReceiver.setText(customerEmail[0]);
                }
            }
        }

        final EditText emailSubject = (EditText) findViewById(R.id.email_subject);
        if (emailSubject != null) {
            emailSubject.setText(mSalesFormEmailJson.EmailMessage.Subject);
        }

        final EditText emailBody = (EditText) findViewById(R.id.email_body);
        if (emailBody != null) {
            emailBody.setText(mSalesFormEmailJson.EmailMessage.Message);
        }

        // The preferences for online payment and bank payment picked up from
        // the transaction object and set on the form.
        final CompoundButton switchCreditCard = (CompoundButton) findViewById(R.id.switch_credit_card);
        mSalesFormEmailJson.AllowOnlineCreditCardPayment = Boolean
                .toString(txnData.mAllow_Online_Credit_Card_Payment);
        if (txnData.mAllow_Online_Credit_Card_Payment) {
            switchCreditCard.setChecked(true);
        } else {
            switchCreditCard.setChecked(false);
        }

        if (Util.shouldBankTransferOptionBeShown()) {
            final CompoundButton switchBankTransfer = (CompoundButton) findViewById(R.id.switch_bank_transfer);
            mSalesFormEmailJson.AllowOnlineACHPayment = Boolean.toString(txnData.getAllow_Online_Ach_Payment());
            if (txnData.getAllow_Online_Ach_Payment()) {
                switchBankTransfer.setChecked(true);
            } else {
                switchBankTransfer.setChecked(false);
            }
        }
    }

    private ProgressDialog mProgress;

    /*
     * This method generates the PDF and downloads the PDF.
     */
    private void preview(Uri pdfUri) {
        CustomLog.logDebug(TAG, "QBOViewTransactionFragment : preview() started");

        final Intent intent = new Intent(this, PreviewService.class);
        intent.setData(pdfUri);
        this.bindService(intent, mPreviewServiceConnection, Context.BIND_AUTO_CREATE);
        this.startService(intent);
        //   TODO P1 : Check if we need to show progress "mProgress" bar here to indicate rendering in pdf viewer.
    }

    /**
     * AIDL class to bind aynchronous request service with this UI element so
     * that it can receive updates
     */
    private ServiceConnection mPreviewServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            final IServiceCallback delegate = IServiceCallback.Stub.asInterface(service);
            try {
                delegate.register(mPreviewCallback);
            } catch (final RemoteException e) {
                CustomLog.logError(TAG, e, "SalesFormEmail : Error with IPC");
            }
        }
    };

    /**
     * AIDL callback method from the service running in the background
     */
    private final IActivityCallback.Stub mPreviewCallback = new IActivityCallback.Stub() {
        @Override
        public void callback(int op, int responseCode, String pMessage) throws RemoteException {
            handlePreviewCallback(op, responseCode, pMessage);
        }

    };

    private void handlePreviewCallback(int op, int responseCode, String pMessage) {
        mPreviewHandler.sendMessage(mPreviewHandler.obtainMessage(op, responseCode, 0, pMessage));
    }

    private String mPDFFileName = null;

    /**
     * invoke the pdf viewer to show the downloaded PDF.
     */
    private void startExternalPreviewActivity() {

        if (hasPreviewLaunched) {
            return;
        }
        hasPreviewLaunched = true;
        // track the launch of external pdf viewer
        //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SFM_OPEN_PDF );
        BaseApplicationModule.getTrackingModule().trackLink(QBMTrackConstants.SALES_FORM_EMAIL_PAGE_NAME,
                QBMTrackConstants.SFM_OPEN_PDF);

        try {
            mPDFFileName = AppPreferences.getStringPreference(this.getApplicationContext(),
                    BaseAppPreferences.PREFS_QBSHAREDLIB, QBODocumentLinkEntity.KEY_PDF_FILENAME, null);
            File file = new File(mPDFFileName);
            Uri fileUri = FileProvider.getUriForFile(this,
                    this.getApplicationContext().getResources().getString(R.string.file_provider_authorities),
                    file);
            Intent intent = new Intent(Intent.ACTION_VIEW);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(fileUri, this.getContentResolver().getType(fileUri));
            startActivity(intent);
        } catch (final ActivityNotFoundException e) {
            displayError(R.string.error_pdf_viewer_not_present, R.string.error_title_error, false);
        }
    }

    private void setPDFHeightUsingWidth() {
        if (mPDFViewCtrl == null) {
            return;
        }

        Configuration configuration = this.getResources().getConfiguration();
        final float deviceDensity = getResources().getDisplayMetrics().density;
        final int screenWidthDp = configuration.screenWidthDp; //The current width of the available screen space, in dp units, corresponding to screen width resource qualifier.

        final int paddingLeftRight = (int) (getResources().getDimension(R.dimen.sales_form_email_form_padding));

        final int pdfContainerWidth = (int) (screenWidthDp * deviceDensity - 2 * paddingLeftRight);

        LayoutParams layParams = mPDFViewCtrl.getLayoutParams();
        layParams.height = (int) (pdfContainerWidth * SalesFormEmail.US_LETTER_HEIGHT_WIDTH_RATIO);
        mPDFViewCtrl.setLayoutParams(layParams);
    }

    /**
     * invoke the pdf viewer to show the downloaded PDF.
     */
    private void startPreviewActivity() {
        try {
            if (mPDFViewCtrl == null) {
                return;
            }

            mPdfLoadingMessage.setVisibility(View.GONE);
            mPDFViewCtrl.setVisibility(View.VISIBLE);

            mPDFViewCtrl.setPageViewMode(PDFViewCtrl.PAGE_VIEW_FIT_WIDTH);

            setPDFHeightUsingWidth();

            mPDFFileName = AppPreferences.getStringPreference(this.getApplicationContext(),
                    BaseAppPreferences.PREFS_QBSHAREDLIB, QBODocumentLinkEntity.KEY_PDF_FILENAME, null);
            File file = new File(mPDFFileName);

            InputStream in = null;
            PDFDoc doc;
            try {
                in = new BufferedInputStream(new FileInputStream(file));
                doc = new PDFDoc(in);
                mPDFViewCtrl.setDoc(doc);
                mPDFViewCtrl.setOnClickListener(this);
            } catch (PDFNetException e) {
                CustomLog.logDebug(TAG, "startPreviewActivity : PDFNetException");
            } catch (IOException e) {
                CustomLog.logDebug(TAG, "startPreviewActivity : IOException");
            } finally {
                if (in != null) {
                    try {
                        in.close();
                    } catch (IOException e) {
                    }
                }
            }
        } catch (final ActivityNotFoundException e) {
            displayError(R.string.error_pdf_viewer_not_present, R.string.error_title_error, false);
        }
    }

    /**
     *    This method handles the click on the row elements on the include in email screen.
     *
     */
    @Override
    public void onClick(View v) {

        final int anId = v.getId();

        if (anId == R.id.pdfviewctrl) {
            startExternalPreviewActivity();
        }
    }

    /**
     * Handle messages being passed from the callback service (it is on a
     * separate thread loop) in case of PreviewService.
     *
     */
    private final Handler mPreviewHandler = new PreviewResponseHandler(this) {
        @Override
        public void onSuccess() {
            stopPreviewProgress();

            startPreviewActivity();
            CustomLog.logDebug(TAG, getClass().getSimpleName() + " : Performance Testing - Preview STOP");
            BaseApplicationModule.getTrackingModule().trackEvent(TrackConstants.TRACK_END_EVENT,
                    QBMTrackConstants.SFM_PDF_LOADED, QBMTrackConstants.SUCCESS);
            // Add success to the flow tracking.
            //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SFM_PDF_LOADED + QBMTrackConstants.SUCCESS);
        }

        @Override
        public void onFailure(int pStringId, int pDisplayFlag) {
            stopPreviewProgress();
            BaseApplicationModule.getTrackingModule().trackEvent(TrackConstants.TRACK_END_EVENT,
                    QBMTrackConstants.SFM_PDF_LOADED, QBMTrackConstants.ERROR);
            // Add success to the flow tracking.
            //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SFM_PDF_LOADED + QBMTrackConstants.ERROR);
            displayError(pStringId, pDisplayFlag, true);
        }

        @Override
        public void onFailure(int pStringId) {
            stopPreviewProgress();

            BaseApplicationModule.getTrackingModule().trackEvent(TrackConstants.TRACK_END_EVENT,
                    QBMTrackConstants.SFM_PDF_LOADED, QBMTrackConstants.ERROR);
            // Add success to the flow tracking.
            //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SFM_PDF_LOADED + QBMTrackConstants.ERROR);
            displayError(pStringId, R.string.error_title_error, false);
        }

        @Override
        public void onFinish() {
            try {
                if (mPreviewServiceConnection != null) {
                    SalesFormEmail.this.unbindService(mPreviewServiceConnection);
                    mPreviewServiceConnection = null;
                }
            } catch (final Exception e) {
                CustomLog.logError(TAG, e, getClass().getSimpleName() + " : Error unbinding Preview service");
            }
        }

    };

    /**
     * Dismiss the Preview progress dialog
     */
    private void stopPreviewProgress() {
        if (mProgress != null && mProgress.isShowing()) {
            mProgress.dismiss();
        }
        if (mPdfLoadingMessage != null) {
            mPdfLoadingMessage.setVisibility(View.GONE);
        }
    }

    /**
     * This method handles the data sync response
     *
     * @param msg
     */
    private void handleDataSyncResponse(Message msg) {

        CustomLog.logDebug(TAG, "Sales form email : " + String
                .format(" Data Service for Sales form email finished with code %s - %s", msg.arg1, msg.obj));
        stopProgressBar();

        // The doNotFinishActivity flag is set to true used when the error needs to be handled in the same activity.
        boolean doNotFinishActivity = false;

        switch (msg.arg1) {
        case Response.RESPONSE_SUCCESS:

            if (mCurrentCommandRequest == ISyncConstants.FLAG_QBO_REFERESH_COMPANY_PREFS_ONLY) {
                doNotFinishActivity = true;
                // show the popup again.
            } else {
                boolean updatePreferenceFailed = "true".equals(msg.obj);
                if (mCurrentCommandRequest == ISyncConstants.FLAG_EDIT_PREF_AND_SEND_MAIL
                        && !updatePreferenceFailed) {
                    // Upon successful update of preference and sending the email. Update preference to not show OTM again.
                    AppPreferences.setBooleanPreference(QBOApplicationModule.getInstance().getApplicationContext(),
                            null, AppPreferences.KEY_ATTACH_PDF_PREFERENCE_OTM_SHOW, false);
                }

                BaseApplicationModule.getTrackingModule().trackEvent(TrackConstants.TRACK_END_EVENT,
                        QBMTrackConstants.SALES_FORM_EMAIL_SENT, QBMTrackConstants.SUCCESS);
                // Add success to the flow tracking.
                //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.SUCCESS);

                if (updatePreferenceFailed) {
                    this.setResult(PSQBOServiceErrorCodes.SALES_FORM_EMAIL_PREFERENCE_UPDATE_ERROR,
                            createIntent((String) msg.obj));
                } else {
                    this.setResult(Activity.RESULT_OK, createIntent((String) msg.obj));
                }
            }
            break;

        case PSQBOServiceErrorCodes.SALES_FORM_EMAIL_DELIVERY_ERROR:
            CustomLog.logDebug(TAG,
                    "SalesFormEmail : ERROR detected details in Transaction Payload" + (String) msg.obj);

            // Add DeliveryError to the flow tracking.
            // SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.DELIVERY_ERROR);
            this.setResult(PSQBOServiceErrorCodes.SALES_FORM_EMAIL_DELIVERY_ERROR, createIntent((String) msg.obj));
            break;

        case IResponseCode.STALE_OBJECT_ERROR_VALUE:
            // Should we have the data sync transaction response handler.
            CustomLog.logDebug(TAG, "SalesFormEmail : Stale object ERROR detected. Showing the refresh dialog. "
                    + (String) msg.obj);

            this.setResult(IErrorCodes.ERROR_REPONSE_INVALID_OBJECT_VERSION, createIntent((String) msg.obj));
            break;

        case IErrorCodes.ERROR_REPONSE_INVALID_OBJECT_VERSION:
            // Should we have the data sync transaction response handler.
            CustomLog.logDebug(TAG, "SalesFormEmail : Stale object ERROR detected. Showing the refresh dialog. "
                    + (String) msg.obj);

            refreshPreferencesDialog();
            doNotFinishActivity = true;
            break;

        default:
            // Should we have the data sync transaction response handler.
            CustomLog.logDebug(TAG, "SalesFormEmail : General ERROR detected " + (String) msg.obj);

            //   TODO P1 - we should probably log this in tracking to explore more in this area.
            // Add Error to the flow tracking.
            //SalesFormEmail.SFM_Flow_tracking = Util.buildTrackingFlow(SalesFormEmail.SFM_Flow_tracking, QBMTrackConstants.ERROR);
            this.setResult(PSQBOServiceErrorCodes.SALES_FORM_EMAIL_GENERAL_DELIVERY_ERROR,
                    createIntent((String) msg.obj));

            break;
        }

        //   Post the flow tracking to omniture
        //    BaseApplicationModule.getTrackingModule().trackPropertyValue(SalesFormEmail.SFM_Flow_tracking);
        //   CustomLog.logDebug(TAG, "Build tracking LOG flow and clear it -------- " + SalesFormEmail.SFM_Flow_tracking);
        if (!doNotFinishActivity) {
            this.finish();
        }
    }

    private AlertDialog.Builder mAlertDialogBuilder = null;

    /*
     *    This method displays a dialog which receives users acknowledgment to refresh preference data.
     */
    private void refreshPreferencesDialog() {
        if (mProgressDialog != null) {
            if (mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
            }
        }
        mAlertDialogBuilder = new AlertDialog.Builder(this);
        mAlertDialogBuilder.setTitle(R.string.new_info_exists)
                .setMessage(R.string.error_sfm_invalid_preference_version_otm).setIcon(R.drawable.ic_dialog_alert)
                .setNegativeButton(R.string.refresh, new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                        refreshPreferenceDataFromServer();
                    }
                }).setOnCancelListener(new OnCancelListener() {
                    @Override
                    public void onCancel(DialogInterface dialog) {
                        dialog.dismiss();
                        finish();
                    }
                }).show();
    }

    /*
     *  This function gets the latest preference data from the server.
     */
    private void refreshPreferenceDataFromServer() {
        //BaseApplicationModule.getTrackingModule().trackLink(getOmnitureTrackerValue(QBMTrackConstants.CONTACT_PAGE_NAME), getOmnitureTrackerValue(QBMTrackConstants.REFRESH_DATA_FROM_SERVER));
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage(getString(R.string.preference_refresh));
        mProgressDialog.show();

        mCurrentCommandRequest = ISyncConstants.FLAG_QBO_REFERESH_COMPANY_PREFS_ONLY;
        GetCompanyPrefDataRequest classRequest = GetCompanyPrefDataRequest.createRequest(getApplicationContext(),
                ISyncConstants.FLAG_QBO_REFERESH_COMPANY_PREFS_ONLY, this, this);
        classRequest.setTag(this);
        BaseApplicationModule.getNetworkModule().dispatchRequest(classRequest);
    }

    /**
     * Start the progress bar
     */
    private void startProgressBar(String msg) {
        mProgressDialog = new ProgressDialog(this);
        mProgressDialog.setMessage(msg);
        mProgressDialog.setCancelable(true);
        mProgressDialog.show();
    }

    /**
     * Stop the progress bar
     */
    private void stopProgressBar() {
        try {
            if (mProgressDialog != null && mProgressDialog.isShowing()) {
                mProgressDialog.dismiss();
                mProgressDialog = null;
            }
        } catch (Exception e) {
            //Absord this as in some cases, the activity is getting destroyed before this is called. If this is the case, we dont need to do
            //much here.
        }
    }

    @Override
    protected void onPause() {
        // This method simply stops the current ongoing rendering thread, text
        // search thread, and tool
        super.onPause();
        if (mPDFViewCtrl != null) {
            mPDFViewCtrl.pause();
        }
        stopProgressBar();
    }

    @Override
    protected void onResume() {
        // This method simply starts the rendering thread to ensure the PDF
        // content is available for viewing.

        super.onResume();

        if (mPDFViewCtrl != null) {
            hasPreviewLaunched = false;
            mPDFViewCtrl.resume();
        }
    }

    /**
     * To delete PDF downloaded by Preview functionality
     */
    private void deletePDF() {
        if (mPDFFileName != null) {
            try {
                final File pdfFile = new File(mPDFFileName);
                //If pdf file exists delete it from memory
                if (pdfFile.exists()) {
                    pdfFile.delete();
                }
            } catch (final Exception e) {
                CustomLog.logError(TAG, e, "Error deleting pdf");
            }
        }
    }

    @Override
    protected void onDestroy() {
        deletePDF();
        if (mPDFViewCtrl != null) {
            mPDFViewCtrl.destroy();
        }
        // Destroy PDFViewCtrl and clean up memory and used resources.
        super.onDestroy();
    }

    @Override
    public void onLowMemory() {
        // Call this method to lower PDFViewCtrl's memory consumption.
        super.onLowMemory();
        if (mPDFViewCtrl != null) {
            mPDFViewCtrl.purgeMemory();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setPDFHeightUsingWidth();
    }

    @Override
    public void onErrorResponse(VolleyError error) {
        if (!isFinishing()) {
            CustomError customError = (CustomError) error;
            onCallback(customError.getRequestCode(), customError.getErrorCode(), customError.getMessage());
        }
    }

    @Override
    public void onResponse(StringResponse response) {
        if (!isFinishing()) {
            onCallback(response.requestCode, response.responseCode, response.data);
        }
    }

}