com.handpoint.headstart.client.ui.ReceiptActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.handpoint.headstart.client.ui.ReceiptActivity.java

Source

/*  Copyright 2013 Handpoint
    
   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at
    
   http://www.apache.org/licenses/LICENSE-2.0
    
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
*/
package com.handpoint.headstart.client.ui;

import javax.mail.MessagingException;
import javax.mail.internet.AddressException;

import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import android.text.Html;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.handpoint.headstart.android.HeadstartService;
import com.handpoint.headstart.api.FinancialTransactionResult;
import com.handpoint.headstart.client.R;
import com.handpoint.headstart.client.android.Application;
import com.handpoint.headstart.client.data.DaoHelper;
import com.handpoint.headstart.client.data.SenderHelper;
import com.handpoint.headstart.client.data.SenderHelper.MerchantEmailServerSettings;
import com.handpoint.headstart.client.data.models.Basket;
import com.handpoint.headstart.client.data.models.BasketItem;
import com.handpoint.headstart.client.data.models.FinancialTransaction;
import com.handpoint.headstart.eft.TransactionStatus;
import com.handpoint.util.logging.ApplicationLogger;
import com.handpoint.util.logging.Level;
import com.handpoint.util.logging.Logger;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.tool.xml.XMLWorkerHelper;
import org.jsoup.Jsoup;

import java.io.*;
import java.nio.charset.Charset;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

public class ReceiptActivity extends HeadstartActivity {
    protected static final String TAG = ReceiptActivity.class.getSimpleName();
    private static Logger logger = ApplicationLogger.getLogger(TAG);

    public static final String EXTRA_TRANSACTION_ID = "com.handpoint.headstart.hal.extra_transaction_id";
    public static final String EXTRA_SEND_MERCHANT_RECEIPT = "com.handpoint.headstart.hal.extra_send_merchant_receipt";

    protected static final int MENU_ITEM_SEND_EMAIL = 1;
    protected static final int MENU_ITEM_SEND_SMS = 2;

    enum EmailTypes {
        MERCHANT, CUSTOMER
    };

    private FinancialTransaction mResult;
    BasketItem mBasketItem;
    private EditText mEmailView;
    private EditText mSmsView;
    private Button mRevertButton;
    private Button mDetailsButton;

    ProgressDialog mPdfDlg;

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.receipt);

        long transactionId = getIntent().getLongExtra(EXTRA_TRANSACTION_ID, -1);
        if (transactionId == -1) {
            finish();
            return;
        }

        DaoHelper daoHelper = new DaoHelper(this);
        daoHelper.open(false);
        mResult = daoHelper.getFinancialTransaction(transactionId);
        Basket basket = daoHelper.getBasketByTransaction(transactionId);
        if (null != basket) {
            mBasketItem = daoHelper.getBasketItem(basket.getId());
        }
        daoHelper.close();
        Button buttonDone = (Button) findViewById(R.id.bottom_button);
        buttonDone.setOnClickListener(new OnClickListener() {

            public void onClick(View v) {
                finish();
            }
        });

        mRevertButton = (Button) findViewById(R.id.revert_button);
        if ((mResult.getType() == FinancialTransactionResult.FT_TYPE_SALE
                || mResult.getType() == FinancialTransactionResult.FT_TYPE_REFUND)
                && null != mResult.getTransactionId() && mResult.getTransactionId().length() > 0
                && mResult.getTransactionStatus() == TransactionStatus.EFT_TRANSACTION_APPROVED
                && 0 == mResult.getVoidedId()) {
            mRevertButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    Intent startVoidIntent = new Intent(HeadstartService.ACTION_MAIN);
                    startVoidIntent.putExtra(HeadstartService.EXTRA_OPERATION_TYPE,
                            mResult.getType() == FinancialTransactionResult.FT_TYPE_SALE
                                    ? FinancialTransactionResult.FT_TYPE_SALE_VOID
                                    : FinancialTransactionResult.FT_TYPE_REFUND_VOID);
                    startVoidIntent.putExtra(HeadstartService.EXTRA_PAYMENT_VALUE, mResult.getAuthorizedAmount());
                    startVoidIntent.putExtra(HeadstartService.EXTRA_PAYMENT_CURRENCY, mResult.getCurrency());
                    startVoidIntent.putExtra(HeadstartService.EXTRA_PAYMENT_TRANSACTION_ID,
                            mResult.getTransactionId());
                    startVoidIntent.putExtra("com.handpoint.headstart.client.VOIDED_ID", mResult.getId());
                    startActivity(startVoidIntent);
                    finish();
                }
            });
        } else {
            mRevertButton.setVisibility(View.GONE);
        }

        mDetailsButton = (Button) findViewById(R.id.details_button);
        if (!TextUtils.isEmpty(mResult.getMerchantReceipt()) || !TextUtils.isEmpty(mResult.getCustomerReceipt())) {
            mDetailsButton.setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(ReceiptActivity.this, RawReceiptActivity.class);
                    intent.putExtra("merchantReceipt", mResult.getMerchantReceipt());
                    intent.putExtra("customerReceipt", mResult.getCustomerReceipt());
                    intent.putExtra("signatureVerificationText", mResult.getSignatureVerificationText());
                    intent.putExtra("signatureImage", mResult.getSignaturePath());
                    startActivity(intent);
                }
            });
        } else {
            mDetailsButton.setVisibility(View.GONE);
        }

        initReceiptView();

        final ImageView sendEmailView = (ImageView) findViewById(R.id.email_send_image);
        mEmailView = (EditText) findViewById(R.id.email_address);

        final ImageView sendSmsView = (ImageView) findViewById(R.id.sms_send_image);
        mSmsView = (EditText) findViewById(R.id.sms_address);

        sendEmailView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                hideSoftKeyboard(mEmailView);
                mPdfDlg = new ProgressDialog(v.getContext());
                mPdfDlg.setMessage(getString(R.string.pdf_dlg_msg));
                mPdfDlg.setTitle(getString(R.string.pdf_dlg_title));
                mPdfDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                mPdfDlg.setCancelable(true);
                mPdfDlg.show();

                new Thread(new Runnable() {
                    public void run() {
                        ArrayList<File> attachments = null;
                        try {
                            Thread.sleep(1000);
                            attachments = getCustomerEmailAttachments();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }

                        if (attachments != null) {
                            try {
                                Thread.sleep(2000);
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                            mPdfDlg.dismiss();

                            SenderHelper.MerchantEmailServerSettings serverSettings = new SenderHelper.MerchantEmailServerSettings(
                                    ReceiptActivity.this);
                            SendAsyncTask sendTask = new SendAsyncTask();
                            sendTask.execute(new EmailDataHolder(ReceiptActivity.this, serverSettings,
                                    mEmailView.getText().toString(), new SpannableString(""), attachments,
                                    EmailTypes.CUSTOMER));
                        }
                    }
                }).start();
            }
        });

        sendSmsView.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                hideSoftKeyboard(mSmsView);
                SenderHelper.sendReceiptSms(ReceiptActivity.this, mSmsView.getText().toString(), mResult);
                //mark customer receipt as "copy"
                markCustomerReceiptAsCopied(ReceiptActivity.this, mResult);
            }
        });

        if (getIntent().getBooleanExtra(EXTRA_SEND_MERCHANT_RECEIPT, false) && savedInstanceState == null) {
            sendMerchantReceipt();
        }

        // repeat image bug fix
        //      View background = findViewById(R.id.rootLayout);
        //      ((BitmapDrawable)background.getBackground()).setTileModeXY(TileMode.REPEAT, TileMode.REPEAT);

        //      getSupportActionBar().setTitle(R.string.abs_title);
        //      getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    }

    void markCustomerReceiptAsCopied(Context ctx, FinancialTransaction result) {
        if (!result.isCustomerReceiptCopy()) {
            DaoHelper dh = new DaoHelper(ctx);
            dh.open(true);
            result.setCustomerReceiptCopy(true);
            dh.updateFinancialTransaction(result);
            dh.close();
        }
    }

    void markMerchantReceiptAsCopied(Context ctx, FinancialTransaction result) {
        if (!result.isMerchantReceiptCopy()) {
            DaoHelper dh = new DaoHelper(ctx);
            dh.open(true);
            result.setMerchantReceiptCopy(true);
            dh.updateFinancialTransaction(result);
            dh.close();
        }
    }

    void hideSoftKeyboard(View v) {
        InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }

    private void initReceiptView() {
        Typeface tf = Typeface.createFromAsset(getAssets(), "fonts/roboto-regular.ttf");

        TextView merchantName = (TextView) findViewById(R.id.merchant_name);
        merchantName.setTypeface(tf, Typeface.BOLD);
        merchantName.setText(getMerchantName());

        TextView transactionDateView = (TextView) findViewById(R.id.date);
        java.text.DateFormat df = DateFormat.getDateFormat(this);
        transactionDateView.setTypeface(tf);
        transactionDateView.setText(" " + df.format(mResult.getDateTime()));

        TextView transactionResult = (TextView) findViewById(R.id.transaction_result);
        transactionResult.setTypeface(tf, Typeface.BOLD);
        transactionResult.setText(mResult.getFinancialStatus());

        TextView messageView = (TextView) findViewById(R.id.message);
        messageView.setTypeface(tf);
        String message = ((Application) getApplication()).formatErrorMessage(mResult.getStatusMessage(),
                mResult.getErrorMessage());
        messageView.setText(message);

        ImageView cardSchemeLogo = (ImageView) findViewById(R.id.card_scheme_logo);
        cardSchemeLogo.setImageDrawable(getCardSchemeLogo());

        TextView amountView = (TextView) findViewById(R.id.amount_text);
        amountView.setTypeface(tf);
        amountView.setText(getTotalAmount(mResult.getAuthorizedAmount(), mResult.getCurrency()));

        TextView descriptionView = (TextView) findViewById(R.id.item_description_text);
        descriptionView.setTypeface(tf);
        descriptionView.setText(getDescriptionText());

        ImageView productImageView = (ImageView) findViewById(R.id.picture);
        productImageView.setImageBitmap(getImageBitmap());
    }

    ArrayList<File> getCustomerEmailAttachments() {
        ArrayList<File> attachments = new ArrayList<File>();
        //get receipt if exists
        File receipt = getCustomerEmailAttachmentFile();
        if (null != receipt)
            attachments.add(receipt);

        //get image if exists
        if (null != mBasketItem && null != mBasketItem.getFullSizePhotoPath()) {
            Uri uri = Uri.parse(mBasketItem.getFullSizePhotoPath());
            File photo = new File(uri.getPath());
            attachments.add(photo);
        }
        return attachments;
    }

    File getCustomerEmailAttachmentFile() {
        String template = getResources().getString(R.string.email_template);
        String html = String.format(template, getDescriptionText(), mResult.getCustomerReceipt());

        return createPdfFromReceipt(html, "customer_");
    }

    private File createPdfFromReceipt(String html, String fileNamePrefix) {
        //We cannot trust that the html is well formed
        org.jsoup.nodes.Document doc = Jsoup.parse(html);
        html = doc.toString();

        File file = null;
        try {
            Document document = new Document(PageSize.LETTER);
            file = getOutputMediaFile(fileNamePrefix);
            PdfWriter instance = PdfWriter.getInstance(document, new FileOutputStream(file));
            document.open();
            InputStream is = new ByteArrayInputStream(html.getBytes());
            XMLWorkerHelper worker = XMLWorkerHelper.getInstance();
            worker.parseXHtml(instance, document, is);
            document.close();

        } catch (Exception e) {
            logger.log(Level.SEVERE, TAG + " :Failed to create .pdf document from receipt.", e);
            Toast.makeText(ReceiptActivity.this, getString(R.string.create_pdf), Toast.LENGTH_LONG).show();
        }
        return file;
    }

    private File getOutputMediaFile(String prefix) {
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)) {
            return null;
        }
        File mediaStorageDir = new File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator
                        + "HandpointProducts");
        if (!mediaStorageDir.exists()) {
            if (!mediaStorageDir.mkdirs()) {
                logger.log(Level.SEVERE, TAG + " :Failed to create directory for storing receipt");
                return null;
            }
        }
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile = new File(mediaStorageDir, prefix + "receipt_" + timeStamp + ".pdf");
        return mediaFile;
    }

    ArrayList<File> getMerchantEmailAttachments() {
        ArrayList<File> attachments = new ArrayList<File>();
        boolean isSignature = false;
        //get signature if any
        if (null != mResult && null != mResult.getSignaturePath()) {
            String path = getFilePathFromContentUrl(mResult.getSignaturePath());
            Uri uri = Uri.parse(path);
            File signature = new File(uri.getPath());
            attachments.add(signature);
            isSignature = true;
        }

        //get receipt if exists
        File receipt = getMerchantEmailAttachmentFile(isSignature);
        if (null != receipt)
            attachments.add(receipt);

        return attachments;
    }

    File getMerchantEmailAttachmentFile(boolean isSignature) {
        String receipt;
        if (isSignature)
            receipt = mResult.getSignatureVerificationText();
        else
            receipt = mResult.getMerchantReceipt();

        String template = getResources().getString(R.string.email_template);
        String html = String.format(template, getDescriptionText(), receipt);

        return createPdfFromReceipt(html, "merchant_");
    }

    Spanned getCustomerEmailText() {
        String template = getResources().getString(R.string.email_template);
        String text = String.format(template, getDescriptionText(),
                getTotalAmount(mResult.getAuthorizedAmount(), mResult.getCurrency()), mResult.getCustomerReceipt());
        return Html.fromHtml(text);

    }

    Spanned getMerchantEmailText() {
        String template = getResources().getString(R.string.email_template);
        String text = String.format(template, getDescriptionText(),
                getTotalAmount(mResult.getAuthorizedAmount(), mResult.getCurrency()), mResult.getMerchantReceipt());
        return Html.fromHtml(text);
    }

    private String getDescriptionText() {
        String description = getResources().getString(R.string.no_description);
        if (null != mBasketItem && !TextUtils.isEmpty(mBasketItem.getDescription())) {
            description = mBasketItem.getDescription();
        }
        return description;
    }

    private Bitmap getImageBitmap() {
        if (null != mBasketItem && null != mBasketItem.getThumbnail()) {
            int len = mBasketItem.getThumbnail().length;
            return BitmapFactory.decodeByteArray(mBasketItem.getThumbnail(), 0, len);
        }
        return null;
    }

    private Drawable getCardSchemeLogo() {
        return ((Application) getApplication()).getCardSchemeLogo(mResult.getCardSchemeName());
    }

    private String getMerchantName() {
        SharedPreferences prefrences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        return prefrences.getString(HeadstartService.PREFERENCE_MERCHANT_NAME, "");
    }

    private String getMerchantEmailAddress() {
        SharedPreferences prefrences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        return prefrences.getString(HeadstartService.PREFERENCE_MERCHANT_EMAIL_ADDRESS, null);
    }

    private String getTotalAmount(Integer totalAmount, String currencyCode) {
        return ((Application) getApplication()).getFormattedAmount(totalAmount, currencyCode);
    }

    private void sendMerchantReceipt() {
        SenderHelper.MerchantEmailServerSettings serverSettings = new SenderHelper.MerchantEmailServerSettings(
                this);
        SendAsyncTask sendTask = new SendAsyncTask();
        sendTask.execute(new EmailDataHolder(this, serverSettings, getMerchantEmailAddress(),
                new SpannableString(""), getMerchantEmailAttachments(), EmailTypes.MERCHANT));
    }

    private String getFilePathFromContentUrl(String url) {
        String[] proj = { MediaStore.Images.Media.DATA };
        CursorLoader loader = new CursorLoader(this, Uri.parse(url), proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }

    private class EmailDataHolder {
        Context ctx;
        MerchantEmailServerSettings serverSettings;
        String emailAddress;
        Spanned emailText;
        ArrayList<File> attachments;
        EmailTypes type;

        public EmailDataHolder(Context ctx, MerchantEmailServerSettings serverSettings, String emailAddress,
                Spanned emailText, ArrayList<File> attachments, EmailTypes type) {
            this.ctx = ctx;
            this.serverSettings = serverSettings;
            this.emailAddress = emailAddress;
            this.emailText = emailText;
            this.attachments = attachments;
            this.type = type;
        }
    }

    private class SendAsyncTask extends AsyncTask<EmailDataHolder, Void, Void> {

        @Override
        protected Void doInBackground(EmailDataHolder... params) {
            try {

                switch (params[0].type) {
                case MERCHANT:
                    boolean resultM = SenderHelper.sendMerchantReceiptEmail(params[0].ctx, params[0].serverSettings,
                            params[0].emailAddress, params[0].emailText, params[0].attachments);
                    //mark customer receipt as "copy"
                    if (resultM) {
                        markMerchantReceiptAsCopied(params[0].ctx, mResult);
                    }
                    break;
                case CUSTOMER:
                    boolean resultC = SenderHelper.sendCustomerReceiptEmail(params[0].ctx, params[0].serverSettings,
                            params[0].emailAddress, params[0].emailText, params[0].attachments);
                    //mark customer receipt as "copy"
                    if (resultC) {
                        markCustomerReceiptAsCopied(params[0].ctx, mResult);
                    }
                    break;
                }
            } catch (AddressException e) {
                logger.log(Level.SEVERE, "Email sending failed", e);
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(ReceiptActivity.this,
                                getString(R.string.error_send_email_failed) + ". "
                                        + getString(R.string.no_merchant_email_error_prompt),
                                Toast.LENGTH_LONG).show();
                    }
                });
            } catch (MessagingException e) {
                logger.log(Level.SEVERE, "Email sending failed", e);
                runOnUiThread(new Runnable() {

                    @Override
                    public void run() {
                        Toast.makeText(ReceiptActivity.this,
                                getString(R.string.error_send_email_failed) + ". "
                                        + getString(R.string.no_server_settings_error_prompt),
                                Toast.LENGTH_LONG).show();
                    }
                });
            }
            return null;
        }

    }
    //   @Override
    //   public boolean onCreateOptionsMenu(Menu menu) {
    //      menu.add(Menu.NONE, MENU_ITEM_SEND_EMAIL, Menu.NONE, R.string.send_email)
    //         .setIcon(R.drawable.menu_ic_email)
    //         .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
    //      menu.add(Menu.NONE, MENU_ITEM_SEND_SMS, Menu.NONE, R.string.send_sms)
    //         .setIcon(R.drawable.menu_ic_sms)
    //         .setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_WITH_TEXT);
    //      return true;
    //   }
    //   
    //    @Override
    //    public boolean onPrepareOptionsMenu(Menu menu) {
    //       if (null == mResult) {
    //          MenuItem item = menu.findItem(MENU_ITEM_SEND_EMAIL);
    //          item.setEnabled(false);
    //          item = menu.findItem(MENU_ITEM_SEND_SMS);
    //          item.setEnabled(false);
    //       }       
    //       return true;
    //    }
    //    
    //   @Override
    //   public boolean onOptionsItemSelected(MenuItem item) {
    //      switch (item.getItemId()) {
    //      case MENU_ITEM_SEND_EMAIL:
    //         SenderHelper.sendReceiptEmail(this, "", null, mResult.customerReceipt);
    //         break;
    //      case MENU_ITEM_SEND_SMS:
    //         SenderHelper.sendReceiptSms(this, mResult);
    //         break;
    //      case android.R.id.home:
    //         finish();
    //         break;
    //      }
    //      return super.onOptionsItemSelected(item);
    //   }

}