blob: 54e208bf0b8eca931fe5ed2402b192f16f5cf7fd [file] [log] [blame]
package org.apache.fineract.ui.online.loanaccounts.loanapplication.loandetails;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.google.android.material.textfield.TextInputLayout;
import androidx.core.widget.NestedScrollView;
import androidx.appcompat.widget.AppCompatSpinner;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.RadioButton;
import com.stepstone.stepper.Step;
import com.stepstone.stepper.VerificationError;
import org.apache.fineract.R;
import org.apache.fineract.data.models.loan.LoanAccount;
import org.apache.fineract.data.models.loan.PaymentCycle;
import org.apache.fineract.data.models.loan.TermRange;
import org.apache.fineract.data.models.product.Product;
import org.apache.fineract.ui.base.FineractBaseActivity;
import org.apache.fineract.ui.base.FineractBaseFragment;
import org.apache.fineract.ui.base.Toaster;
import org.apache.fineract.ui.online.loanaccounts.loanapplication.OnNavigationBarListener;
import org.apache.fineract.utils.Utils;
import org.apache.fineract.utils.ValidateIdentifierUtil;
import org.apache.fineract.utils.ValidationUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.inject.Inject;
import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
/**
* @author Rajan Maurya
* On 17/07/17.
*/
public class LoanDetailsFragment extends FineractBaseFragment implements Step,
LoanDetailsContract.View, AdapterView.OnItemSelectedListener, TextWatcher {
public static final String LOG_TAG = LoanDetailsFragment.class.getSimpleName();
@BindView(R.id.ncv_loan_details)
NestedScrollView ncvLoanDetails;
@BindView(R.id.sp_products)
AppCompatSpinner spProducts;
@BindView(R.id.til_short_name)
TextInputLayout tilShortName;
@BindView(R.id.et_short_name)
EditText etShortName;
@BindView(R.id.et_principal_amount)
EditText etPrincipalAmount;
@BindView(R.id.til_principal_amount)
TextInputLayout tilPrincipalAmount;
@BindView(R.id.et_term)
EditText etTerm;
@BindView(R.id.til_term)
TextInputLayout tilTerm;
@BindView(R.id.sp_term_unit_type)
AppCompatSpinner spTermUnitType;
@BindView(R.id.et_repay)
EditText etRepay;
@BindView(R.id.til_repay)
TextInputLayout tilRepay;
@BindView(R.id.sp_repay_unit_type)
AppCompatSpinner spRepayUnitType;
@BindView(R.id.ll_repay_unit_week)
LinearLayout llRepayUnitWeek;
@BindView(R.id.ll_repay_unit_year)
LinearLayout llRepayUnitYear;
@BindView(R.id.sp_repay_unit_week)
AppCompatSpinner spRepayUnitTypeWeek;
@BindView(R.id.ll_repay_unit_month)
LinearLayout llRepayUnitMonth;
@BindView(R.id.rb_repay_on_day)
RadioButton rbRepayOnDay;
@BindView(R.id.rb_repay_on_specific_week_day)
RadioButton rbRepayOnSpecificDay;
@BindView(R.id.sp_repay_month_day_in_number)
AppCompatSpinner spRepayMonthDayInNumber;
@BindView(R.id.sp_repay_time_slots)
AppCompatSpinner spRepayTimeSlots;
@BindView(R.id.sp_repay_week_days)
AppCompatSpinner spRepayWeekDays;
@BindView(R.id.sp_repay_year_month)
AppCompatSpinner spRepayYearMonth;
@BindView(R.id.layout_error)
View layoutError;
View rootView;
@Inject
LoanDetailsPresenter loanDetailsPresenter;
private OnNavigationBarListener.LoanDetailsData onNavigationBarListener;
private List<String> products;
private List<String> repayUnitType;
private List<String> ternUnitType;
private List<String> timeSlots;
private List<String> weeks;
private List<String> months;
private List<String> monthsNumber;
private Product product;
private ArrayAdapter<String> productsAdapter;
private ArrayAdapter<String> termUnitTypeAdapter;
public static LoanDetailsFragment newInstance() {
LoanDetailsFragment fragment = new LoanDetailsFragment();
Bundle args = new Bundle();
fragment.setArguments(args);
return fragment;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
((FineractBaseActivity) getActivity()).getActivityComponent().inject(this);
setRetainInstance(true);
products = new ArrayList<>();
ternUnitType = new ArrayList<>();
repayUnitType = new ArrayList<>(Arrays.asList(
getActivity().getResources().getStringArray(R.array.repay_unit_type)));
timeSlots = new ArrayList<>(Arrays.asList(
getActivity().getResources().getStringArray(R.array.time_slots)));
weeks = new ArrayList<>(Arrays.asList(
getActivity().getResources().getStringArray(R.array.week_names)));
months = new ArrayList<>(Arrays.asList(
getActivity().getResources().getStringArray(R.array.month_names)));
monthsNumber = new ArrayList<>(Arrays.asList(
getActivity().getResources().getStringArray(R.array.repay_on_months)));
}
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.fragment_loan_details, container, false);
ButterKnife.bind(this, rootView);
initializeFineractUIErrorHandler(getActivity(), rootView);
loanDetailsPresenter.attachView(this);
showUserInterface();
loanDetailsPresenter.fetchProducts();
return rootView;
}
@OnClick(R.id.btn_try_again)
void reloadProducts() {
layoutError.setVisibility(View.GONE);
ncvLoanDetails.setVisibility(View.GONE);
loanDetailsPresenter.fetchProducts();
}
@Override
public VerificationError verifyStep() {
if (!validateShortName() || !validateTerm() || !validateRepay()
|| !validatePrincipalAmount()) {
return new VerificationError(null);
} else {
PaymentCycle paymentCycle = new PaymentCycle();
paymentCycle.setPeriod(Integer.parseInt(etRepay.getText().toString().trim()));
paymentCycle.setTemporalUnit(
spRepayUnitType.getSelectedItem().toString().toUpperCase());
switch (spRepayUnitType.getSelectedItemPosition()) {
case 0:
paymentCycle.setAlignmentDay(spRepayUnitTypeWeek.getSelectedItemPosition());
break;
case 1:
if (rbRepayOnDay.isChecked()) {
paymentCycle.setAlignmentDay(
spRepayMonthDayInNumber.getSelectedItemPosition());
} else if (rbRepayOnSpecificDay.isChecked()) {
paymentCycle.setAlignmentDay(spRepayWeekDays.getSelectedItemPosition());
paymentCycle.setAlignmentMonth(null);
paymentCycle.setAlignmentWeek(spRepayTimeSlots.getSelectedItemPosition());
}
break;
case 2:
if (rbRepayOnDay.isChecked()) {
paymentCycle.setAlignmentDay(
spRepayMonthDayInNumber.getSelectedItemPosition());
} else if (rbRepayOnSpecificDay.isChecked()) {
paymentCycle.setAlignmentDay(spRepayWeekDays.getSelectedItemPosition());
paymentCycle.setAlignmentMonth(null);
paymentCycle.setAlignmentWeek(spRepayTimeSlots.getSelectedItemPosition());
}
paymentCycle.setAlignmentMonth(spRepayYearMonth.getSelectedItemPosition());
break;
}
onNavigationBarListener.setLoanDetails(LoanAccount.State.CREATED,
etShortName.getText().toString().trim(), product.getIdentifier(),
Double.parseDouble(etPrincipalAmount.getText().toString().trim()),
paymentCycle, new TermRange(product.getTermRange().getTemporalUnit(),
Double.parseDouble(etTerm.getText().toString().trim()))
, spProducts.getSelectedItem().toString());
return null;
}
}
@Override
public void onSelected() {
// when every condition will fine in verifyStep();
}
@Override
public void onError(@NonNull VerificationError error) {
// Make changes on UI, If error occurred
}
@OnClick(R.id.rb_repay_on_day)
void repayOnDay() {
spRepayMonthDayInNumber.setEnabled(true);
spRepayTimeSlots.setEnabled(false);
spRepayWeekDays.setEnabled(false);
}
@OnClick(R.id.rb_repay_on_specific_week_day)
void repayOnSpecificDay() {
spRepayMonthDayInNumber.setEnabled(false);
spRepayTimeSlots.setEnabled(true);
spRepayWeekDays.setEnabled(true);
}
@Override
public void showUserInterface() {
productsAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, products);
productsAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spProducts.setAdapter(productsAdapter);
spProducts.setOnItemSelectedListener(this);
ArrayAdapter<String> repayUnitAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, repayUnitType);
repayUnitAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayUnitType.setAdapter(repayUnitAdapter);
spRepayUnitType.setOnItemSelectedListener(this);
ArrayAdapter<String> repayUnitTypeWeekAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, weeks);
repayUnitTypeWeekAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayUnitTypeWeek.setAdapter(repayUnitTypeWeekAdapter);
spRepayUnitTypeWeek.setOnItemSelectedListener(this);
ArrayAdapter<String> repayUnitTypeMonthTimeSlotsAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_gallery_item, timeSlots);
repayUnitTypeMonthTimeSlotsAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayTimeSlots.setAdapter(repayUnitTypeMonthTimeSlotsAdapter);
spRepayTimeSlots.setOnItemSelectedListener(this);
ArrayAdapter<String> repayUnitTypeMonthWeeksAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_gallery_item, weeks);
repayUnitTypeMonthWeeksAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayWeekDays.setAdapter(repayUnitTypeMonthWeeksAdapter);
spRepayWeekDays.setOnItemSelectedListener(this);
ArrayAdapter<String> repayUnitTypeYearMonthsAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_spinner_item, months);
repayUnitTypeYearMonthsAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayYearMonth.setAdapter(repayUnitTypeYearMonthsAdapter);
spRepayYearMonth.setOnItemSelectedListener(this);
ArrayAdapter<String> repayMonthDayInNumberAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_gallery_item, monthsNumber);
repayMonthDayInNumberAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spRepayMonthDayInNumber.setAdapter(repayMonthDayInNumberAdapter);
spRepayMonthDayInNumber.setOnItemSelectedListener(this);
termUnitTypeAdapter = new ArrayAdapter<>(getActivity(),
android.R.layout.simple_gallery_item, ternUnitType);
termUnitTypeAdapter.setDropDownViewResource(
android.R.layout.simple_spinner_dropdown_item);
spTermUnitType.setAdapter(termUnitTypeAdapter);
spTermUnitType.setOnItemSelectedListener(this);
etPrincipalAmount.addTextChangedListener(this);
etTerm.addTextChangedListener(this);
etRepay.addTextChangedListener(this);
etShortName.addTextChangedListener(this);
spRepayMonthDayInNumber.setEnabled(true);
spRepayTimeSlots.setEnabled(false);
spRepayWeekDays.setEnabled(false);
rbRepayOnDay.setChecked(true);
}
@Override
public void showProducts(List<String> products) {
ncvLoanDetails.setVisibility(View.VISIBLE);
layoutError.setVisibility(View.GONE);
this.products.addAll(products);
productsAdapter.notifyDataSetChanged();
}
@Override
public void setComponentsValidations(Product product) {
this.product = product;
etPrincipalAmount.setText(String.valueOf(product.getBalanceRange().getMinimum()));
ternUnitType.clear();
ternUnitType.addAll(loanDetailsPresenter.getCurrentTermUnitType(
repayUnitType, product.getTermRange().getTemporalUnit()));
termUnitTypeAdapter.notifyDataSetChanged();
spTermUnitType.setEnabled(false);
etTerm.setText("1");
etRepay.setText("1");
}
@Override
public void showEmptyProducts() {
ncvLoanDetails.setVisibility(View.VISIBLE);
layoutError.setVisibility(View.GONE);
Toaster.show(rootView, getString(R.string.empty_create_loan_products), Toaster.INDEFINITE);
}
@Override
public void showProgressbar() {
showMifosProgressBar();
}
@Override
public void hideProgressbar() {
hideMifosProgressBar();
}
@Override
public void showNoInternetConnection() {
ncvLoanDetails.setVisibility(View.GONE);
layoutError.setVisibility(View.VISIBLE);
showFineractNoInternetUI();
}
@Override
public void showError(String message) {
ncvLoanDetails.setVisibility(View.GONE);
layoutError.setVisibility(View.VISIBLE);
showFineractErrorUI(getString(R.string.products));
}
@Override
public boolean validateShortName() {
return ValidateIdentifierUtil.isValid(getActivity(),
etShortName.getText().toString().trim(), tilShortName);
}
@Override
public boolean validateTerm() {
try {
Double minimum = 1.0;
Double maximum = product.getTermRange().getMaximum();
Double value = Double.parseDouble(etTerm.getText().toString());
if (etTerm.getText().toString().equals("")) {
ValidationUtil.showTextInputLayoutError(tilTerm, getString(R.string.required));
return false;
} else if (!(minimum <= value)) {
ValidationUtil.showTextInputLayoutError(tilTerm,
getString(R.string.value_must_greater_or_equal_to,
Utils.getPrecision(minimum)));
return false;
} else if (!(value <= maximum)) {
ValidationUtil.showTextInputLayoutError(tilTerm,
getString(R.string.value_must_less_than_or_equal_to,
Utils.getPrecision(maximum)));
return false;
}
} catch (NumberFormatException e) {
ValidationUtil.showTextInputLayoutError(tilTerm,
getString(R.string.required));
return false;
}
ValidationUtil.hideTextInputLayoutError(tilTerm);
return true;
}
@Override
public boolean validatePrincipalAmount() {
try {
Double minimum = product.getBalanceRange().getMinimum();
Double maximum = product.getBalanceRange().getMaximum();
Double value = Double.parseDouble(etPrincipalAmount.getText().toString());
if (etPrincipalAmount.getText().toString().equals("")) {
ValidationUtil.isEmpty(getActivity(),
etPrincipalAmount.getText().toString().trim(), tilPrincipalAmount);
return false;
} else if (!(minimum <= value)) {
ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
getString(R.string.value_must_greater_or_equal_to,
Utils.getPrecision(minimum)));
return false;
} else if (!(value <= maximum)) {
ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
getString(R.string.value_must_less_than_or_equal_to,
Utils.getPrecision(maximum)));
return false;
}
} catch (NumberFormatException e) {
ValidationUtil.showTextInputLayoutError(tilPrincipalAmount,
getString(R.string.required));
return false;
}
ValidationUtil.hideTextInputLayoutError(tilPrincipalAmount);
return true;
}
@Override
public boolean validateRepay() {
return ValidationUtil.isEmpty(getActivity(),
etRepay.getText().toString().trim(), tilRepay);
}
@Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
switch (parent.getId()) {
case R.id.sp_products:
loanDetailsPresenter.setProductPositionAndValidateViews(position);
break;
case R.id.sp_repay_unit_type:
switch (position) {
case 0:
llRepayUnitWeek.setVisibility(View.VISIBLE);
llRepayUnitMonth.setVisibility(View.GONE);
llRepayUnitYear.setVisibility(View.GONE);
break;
case 1:
llRepayUnitWeek.setVisibility(View.GONE);
llRepayUnitMonth.setVisibility(View.VISIBLE);
llRepayUnitYear.setVisibility(View.GONE);
break;
case 2:
llRepayUnitWeek.setVisibility(View.GONE);
llRepayUnitMonth.setVisibility(View.VISIBLE);
llRepayUnitYear.setVisibility(View.VISIBLE);
break;
}
break;
}
}
@Override
public void onNothingSelected(AdapterView<?> parent) {
}
@Override
public void onDestroyView() {
super.onDestroyView();
hideMifosProgressBar();
loanDetailsPresenter.detachView();
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
Activity activity = context instanceof Activity ? (Activity) context : null;
try {
onNavigationBarListener = (OnNavigationBarListener.LoanDetailsData) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnNavigationBarListener");
}
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (etPrincipalAmount.getText().hashCode() == s.hashCode()) {
validatePrincipalAmount();
} else if (etTerm.getText().hashCode() == s.hashCode()) {
validateTerm();
} else if (etRepay.getText().hashCode() == s.hashCode()) {
validateRepay();
} else if (etShortName.getText().hashCode() == s.hashCode()) {
validateShortName();
}
}
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putStringArrayList("products", (ArrayList<String>) products);
super.onSaveInstanceState(outState);
}
}