com.brq.wallet.external.cashila.activity.CashilaNewFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.brq.wallet.external.cashila.activity.CashilaNewFragment.java

Source

/*
 * Copyright 2013, 2014 Megion Research and Development GmbH
 *
 * Licensed under the Microsoft Reference Source License (MS-RSL)
 *
 * This license governs use of the accompanying software. If you use the software, you accept this license.
 * If you do not accept the license, do not use the software.
 *
 * 1. Definitions
 * The terms "reproduce," "reproduction," and "distribution" have the same meaning here as under U.S. copyright law.
 * "You" means the licensee of the software.
 * "Your company" means the company you worked for when you downloaded the software.
 * "Reference use" means use of the software within your company as a reference, in read only form, for the sole purposes
 * of debugging your products, maintaining your products, or enhancing the interoperability of your products with the
 * software, and specifically excludes the right to distribute the software outside of your company.
 * "Licensed patents" means any Licensor patent claims which read directly on the software as distributed by the Licensor
 * under this license.
 *
 * 2. Grant of Rights
 * (A) Copyright Grant- Subject to the terms of this license, the Licensor grants you a non-transferable, non-exclusive,
 * worldwide, royalty-free copyright license to reproduce the software for reference use.
 * (B) Patent Grant- Subject to the terms of this license, the Licensor grants you a non-transferable, non-exclusive,
 * worldwide, royalty-free patent license under licensed patents for reference use.
 *
 * 3. Limitations
 * (A) No Trademark License- This license does not grant you any rights to use the Licensors name, logo, or trademarks.
 * (B) If you begin patent litigation against the Licensor over patents that you think may apply to the software
 * (including a cross-claim or counterclaim in a lawsuit), your license to the software ends automatically.
 * (C) The software is licensed "as-is." You bear the risk of using it. The Licensor gives no express warranties,
 * guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot
 * change. To the extent permitted under your local laws, the Licensor excludes the implied warranties of merchantability,
 * fitness for a particular purpose and non-infringement.
 */

package com.brq.wallet.external.cashila.activity;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import butterknife.*;

import com.brq.wallet.Utils;
import com.brq.wallet.external.cashila.api.request.CreateBillPayBasedOnRecent;
import com.brq.wallet.external.cashila.api.response.BillPay;
import com.brq.wallet.external.cashila.api.response.BillPayExistingRecipient;
import com.google.api.client.util.Strings;
import com.google.common.base.Optional;
import com.mrd.bitlib.model.Address;
import com.brq.wallet.MbwManager;
import com.brq.wallet.R;
import com.brq.wallet.activity.modern.Toaster;
import com.brq.wallet.external.cashila.api.CashilaService;
import com.brq.wallet.external.cashila.api.request.CreateBillPay;
import com.brq.wallet.external.cashila.api.response.AccountLimits;
import com.mycelium.wapi.api.response.Feature;
import com.squareup.otto.Bus;
import rx.Observer;
import rx.android.schedulers.AndroidSchedulers;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.List;
import java.util.UUID;

/**
 * The "new payment" fragment
 */
public class CashilaNewFragment extends Fragment {
    @BindView(R.id.spRecipients)
    public Spinner spRecipients;
    @BindView(R.id.etAmount)
    public EditText etAmount;
    @BindView(R.id.etReference)
    public EditText etReference;
    @BindView(R.id.tvMinMaxAmount)
    TextView tvMinMaxAmount;

    RecipientArrayAdapter recipientArrayAdapter;
    private CashilaService cs;
    private MbwManager mbw;
    private Bus eventBus;
    private AccountLimits.Limits currentAccountLimits;
    private UUID toSelect;
    private Unbinder unbinder;

    /**
     * Returns a new instance of this fragment for the given section
     * number.
     */
    public static CashilaNewFragment newInstance() {
        CashilaNewFragment fragment = new CashilaNewFragment();
        Bundle args = new Bundle();
        fragment.setArguments(args);
        return fragment;
    }

    public CashilaNewFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.ext_cashila_payments_fragment_new, container, false);
        unbinder = ButterKnife.bind(this, rootView);

        mbw = MbwManager.getInstance(this.getActivity());
        cs = ((CashilaPaymentsActivity) getActivity()).getCashilaService();
        eventBus = mbw.getEventBus();

        int selItem = 0;
        if (savedInstanceState != null) {
            selItem = savedInstanceState.getInt("spRecipient", 0);
            currentAccountLimits = (AccountLimits.Limits) savedInstanceState.getSerializable("accountLimits");
            showAccountLimits();
        }

        // use cache if possible
        getRecentRecipientsList(selItem, true);

        return rootView;
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt("spRecipient", spRecipients.getSelectedItemPosition());
        outState.putSerializable("accountLimits", currentAccountLimits);
    }

    private void getRecentRecipientsList(final int selItem, boolean fromCache) {
        final ProgressDialog progressDialog = ProgressDialog.show(this.getActivity(),
                getResources().getString(R.string.cashila), getResources().getString(R.string.cashila_fetching),
                true);

        // ensure login and get the list of all recipients
        cs.getBillPaysRecent(fromCache).observeOn(AndroidSchedulers.mainThread())
                // this must be an Observer (not a Action1), otherwise the error-propagation does not work
                .subscribe(new Observer<List<BillPayExistingRecipient>>() {
                    @Override
                    public void onCompleted() {
                        progressDialog.dismiss();
                    }

                    @Override
                    public void onError(Throwable e) {
                        progressDialog.dismiss();
                    }

                    @Override
                    public void onNext(List<BillPayExistingRecipient> listCashilaResponse) {
                        if (listCashilaResponse.size() == 0) {
                            Utils.showSimpleMessageDialog(getActivity(),
                                    getResources().getString(R.string.cashila_no_recipients), new Runnable() {
                                        @Override
                                        public void run() {
                                            ((CashilaPaymentsActivity) getActivity()).openAddRecipient();

                                        }
                                    });

                        } else {
                            recipientArrayAdapter = new RecipientArrayAdapter(getActivity(), listCashilaResponse);
                            spRecipients.setAdapter(recipientArrayAdapter);

                            // if we got a uuid to select the current recipient, sarch through the list, if we have it
                            // and select it
                            if (toSelect != null) {
                                int count = 0;
                                for (BillPayExistingRecipient recipient : listCashilaResponse) {
                                    if (recipient.id.equals(toSelect.toString())) {
                                        spRecipients.setSelection(count);
                                        break;
                                    }
                                    count++;
                                }
                            } else {
                                spRecipients.setSelection(selItem);
                            }
                        }

                        // fetch account limits, if none are available
                        updateAccountLimits();
                    }
                });
    }

    public void selectRecipient(UUID recipientId, boolean fromCache) {
        toSelect = recipientId;
        // fetch the list from the server again and try to select by uuid, if it fails, select the first one
        getRecentRecipientsList(0, fromCache);
    }

    private void updateAccountLimits() {
        // ensure login and get the list of all recipients
        cs.getAccountLimit().observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<AccountLimits>() {
            @Override
            public void onCompleted() {
            }

            @Override
            public void onError(Throwable e) {
            }

            @Override
            public void onNext(AccountLimits accountLimits) {
                if (accountLimits.containsKey("EUR")) {
                    currentAccountLimits = accountLimits.get("EUR");
                    showAccountLimits();
                }
            }
        });

    }

    private void showAccountLimits() {
        if (currentAccountLimits != null) {
            final DecimalFormat decimal = new DecimalFormat("#0.00");
            tvMinMaxAmount.setText(String.format("(min: %s / max: %s)",
                    decimal.format(currentAccountLimits.min), decimal.format(currentAccountLimits.max)));
        }
        onTextAmount();
    }

    boolean amountIsWithinLimits() {
        final BigDecimal amount = getAmount();
        return (amount != null && currentAccountLimits != null) && !(amount.compareTo(currentAccountLimits.max) > 0
                || amount.compareTo(currentAccountLimits.min) < 0);
    }

    @OnTextChanged(R.id.etAmount)
    void onTextAmount() {
        final BigDecimal amount = getAmount();
        // mark the min/max text field red, if amount is outside the bounds
        if (amount != null && currentAccountLimits != null) {
            if (amountIsWithinLimits()) {
                tvMinMaxAmount.setTextColor(getResources().getColor(R.color.lightgrey));
            } else {
                tvMinMaxAmount.setTextColor(getResources().getColor(R.color.status_red));
            }
        } else {
            tvMinMaxAmount.setTextColor(getResources().getColor(R.color.lightgrey));
        }
    }

    public void refresh() {
        getRecentRecipientsList(spRecipients.getSelectedItemPosition(), false);
    }

    private CreateBillPay getBillPayFromUserEntry() {
        BillPayExistingRecipient selectedItem = (BillPayExistingRecipient) spRecipients.getSelectedItem();
        if (selectedItem == null) {
            return null;
        }

        BigDecimal amount = getAmount();
        if (amount == null) {
            return null;
        }

        Optional<Address> receivingAddress = mbw.getSelectedAccount().getReceivingAddress();
        if (!receivingAddress.isPresent()) {
            return null;
        }

        return new CreateBillPayBasedOnRecent(UUID.fromString(selectedItem.id), amount, "EUR",
                etReference.getText().toString(), receivingAddress.get());
    }

    private CreateBillPay getBillPay() {
        return getBillPayFromUserEntry();
    }

    private BigDecimal getAmount() {
        DecimalFormat numberFormat = (DecimalFormat) DecimalFormat.getNumberInstance(mbw.getLocale());
        BigDecimal amount;

        try {
            String amountText = etAmount.getText().toString();
            if (Strings.isNullOrEmpty(amountText)) {
                return null;
            }

            char decimalSeparator = numberFormat.getDecimalFormatSymbols().getDecimalSeparator();

            // the num entry on (some?) android defaults to "." as decimal separator, no matter
            // what locale the user has chosen
            if (decimalSeparator == '.') {
                amountText = amountText.replace(',', decimalSeparator);
            } else {
                amountText = amountText.replace('.', decimalSeparator);
            }

            amount = new BigDecimal(numberFormat.parse(amountText).doubleValue());
        } catch (ParseException e) {
            new Toaster(getActivity()).toast(getResources().getString(R.string.cashila_amount_not_valid), true);
            return null;
        }
        return amount;
    }

    @OnClick(R.id.ibAddRecipient)
    public void onAddRecipient() {
        ((CashilaPaymentsActivity) getActivity()).openAddRecipient();
    }

    @OnClick(R.id.btPayNow)
    public void onPayNow() {
        final CreateBillPay newBillPay = getBillPay();
        if (newBillPay != null) {
            mbw.getVersionManager().showFeatureWarningIfNeeded(getActivity(), Feature.CASHILA_NEW_PAYMENT, true,
                    new Runnable() {

                        @Override
                        public void run() {
                            UUID newUuid = UUID.randomUUID();
                            cs.createBillPay(newUuid, newBillPay).observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Observer<BillPay>() {
                                        @Override
                                        public void onCompleted() {
                                            etAmount.setText("");
                                            etReference.setText("");
                                            // clear current Account limit cache, as it might change later on
                                            currentAccountLimits = null;
                                        }

                                        @Override
                                        public void onError(Throwable e) {
                                        }

                                        @Override
                                        public void onNext(BillPay billPay) {
                                            eventBus.post(billPay);
                                        }
                                    });
                        }
                    });
        }
    }

    @OnClick(R.id.btEnqueue)
    public void onEnqueue() {
        final CreateBillPay newBillPay = getBillPay();
        if (newBillPay != null) {
            mbw.getVersionManager().showFeatureWarningIfNeeded(getActivity(), Feature.CASHILA_NEW_PAYMENT, true,
                    new Runnable() {
                        @Override
                        public void run() {
                            UUID newUuid = UUID.randomUUID();
                            cs.createBillPay(newUuid, newBillPay).observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Observer<BillPay>() {
                                        @Override
                                        public void onCompleted() {
                                            etAmount.setText("");
                                            etReference.setText("");
                                            ((CashilaPaymentsActivity) getActivity()).setCurrentPage(1);
                                            ((CashilaPaymentsActivity) getActivity()).updatePayments();
                                        }

                                        @Override
                                        public void onError(Throwable e) {

                                        }

                                        @Override
                                        public void onNext(BillPay billPay) {
                                            Log.i("cashila", billPay.toString());
                                        }
                                    });
                        }
                    });

        }
    }

    @Override
    public void onDestroy() {
        unbinder.unbind();
        super.onDestroy();
    }

    @Override
    public void onPause() {
        mbw.getVersionManager().closeDialog();
        super.onPause();
    }

    // Adapter for Recipient Spinner
    public static class RecipientArrayAdapter extends ArrayAdapter<BillPayExistingRecipient> {
        private final LayoutInflater inflater;

        public RecipientArrayAdapter(Context context, List<BillPayExistingRecipient> elems) {
            super(context, 0, elems);
            inflater = LayoutInflater.from(context);
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = inflater.inflate(R.layout.ext_cashila_recipient_row, null);
            }

            TextView tvName = ButterKnife.findById(convertView, R.id.tvName);
            TextView tvInfo = ButterKnife.findById(convertView, R.id.tvInfo);

            BillPayExistingRecipient recipient = getItem(position);

            tvName.setText(recipient.name);
            if (recipient.label != null && !recipient.label.isEmpty()) {
                tvInfo.setText(recipient.label);
            } else {
                tvInfo.setText(recipient.city + ", " + recipient.countryName);
            }
            return convertView;
        }

        @Override
        public View getDropDownView(int position, View convertView, ViewGroup parent) {
            return getView(position, convertView, parent);
        }
    }

}