From 2780d22c9b11fcd67eff8f839e4b25f8facd25c1 Mon Sep 17 00:00:00 2001 From: Damyan Ivanov Date: Fri, 7 May 2021 23:47:39 +0300 Subject: [PATCH] show current account balance when choosing account in new transactions --- .../net/ktnx/mobileledger/dao/AccountDAO.java | 24 ++-- .../db/AccountAutocompleteAdapter.java | 10 +- .../mobileledger/db/AccountWithAmounts.java | 6 + ...AccountWithAmountsAutocompleteAdapter.java | 109 ++++++++++++++++++ .../NewTransactionAccountRowItemHolder.java | 11 +- .../res/layout/account_autocomplete_row.xml | 50 ++++++++ 6 files changed, 193 insertions(+), 17 deletions(-) create mode 100644 app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmountsAutocompleteAdapter.java create mode 100644 app/src/main/res/layout/account_autocomplete_row.xml diff --git a/app/src/main/java/net/ktnx/mobileledger/dao/AccountDAO.java b/app/src/main/java/net/ktnx/mobileledger/dao/AccountDAO.java index 429e1643..0cfed1b6 100644 --- a/app/src/main/java/net/ktnx/mobileledger/dao/AccountDAO.java +++ b/app/src/main/java/net/ktnx/mobileledger/dao/AccountDAO.java @@ -106,9 +106,9 @@ public abstract class AccountDAO extends BaseDAO { " ELSE 9 END AS ordering " + "FROM accounts " + "WHERE profile_id=:profileId AND name_upper LIKE '%%'||:term||'%%' " + "ORDER BY ordering, name_upper, rowid ") - public abstract LiveData> lookupInProfileByName(long profileId, - @NonNull - String term); + public abstract LiveData> lookupNamesInProfileByName(long profileId, + @NonNull + String term); @Query("SELECT name, CASE WHEN name_upper LIKE :term||'%%' THEN 1 " + " WHEN name_upper LIKE '%%:'||:term||'%%' THEN 2 " + @@ -116,22 +116,32 @@ public abstract class AccountDAO extends BaseDAO { " ELSE 9 END AS ordering " + "FROM accounts " + "WHERE profile_id=:profileId AND name_upper LIKE '%%'||:term||'%%' " + "ORDER BY ordering, name_upper, rowid ") - public abstract List lookupInProfileByNameSync(long profileId, - @NonNull String term); + public abstract List lookupNamesInProfileByNameSync(long profileId, + @NonNull String term); + + @Query("SELECT * FROM accounts " + + "WHERE profile_id=:profileId AND name_upper LIKE '%%'||:term||'%%' " + + "ORDER BY CASE WHEN name_upper LIKE :term||'%%' THEN 1 " + + " WHEN name_upper LIKE '%%:'||:term||'%%' THEN 2 " + + " WHEN name_upper LIKE '%% '||:term||'%%' THEN 3 " + + " ELSE 9 END, name_upper, rowid ") + public abstract List lookupWithAmountsInProfileByNameSync(long profileId, + @NonNull + String term); @Query("SELECT DISTINCT name, CASE WHEN name_upper LIKE :term||'%%' THEN 1 " + " WHEN name_upper LIKE '%%:'||:term||'%%' THEN 2 " + " WHEN name_upper LIKE '%% '||:term||'%%' THEN 3 " + " ELSE 9 END AS ordering " + "FROM accounts " + "WHERE name_upper LIKE '%%'||:term||'%%' " + "ORDER BY ordering, name_upper, rowid ") - public abstract LiveData> lookupByName(@NonNull String term); + public abstract LiveData> lookupNamesByName(@NonNull String term); @Query("SELECT DISTINCT name, CASE WHEN name_upper LIKE :term||'%%' THEN 1 " + " WHEN name_upper LIKE '%%:'||:term||'%%' THEN 2 " + " WHEN name_upper LIKE '%% '||:term||'%%' THEN 3 " + " ELSE 9 END AS ordering " + "FROM accounts " + "WHERE name_upper LIKE '%%'||:term||'%%' " + "ORDER BY ordering, name_upper, rowid ") - public abstract List lookupByNameSync(@NonNull String term); + public abstract List lookupNamesByNameSync(@NonNull String term); @Query("SELECT * FROM accounts WHERE profile_id = :profileId") public abstract List allForProfileSync(long profileId); diff --git a/app/src/main/java/net/ktnx/mobileledger/db/AccountAutocompleteAdapter.java b/app/src/main/java/net/ktnx/mobileledger/db/AccountAutocompleteAdapter.java index 76673edf..6a92b617 100644 --- a/app/src/main/java/net/ktnx/mobileledger/db/AccountAutocompleteAdapter.java +++ b/app/src/main/java/net/ktnx/mobileledger/db/AccountAutocompleteAdapter.java @@ -75,11 +75,11 @@ public class AccountAutocompleteAdapter extends ArrayAdapter { Logger.debug("acc", String.format("Looking for account '%s'", constraint)); final List matches = AccountDAO.unbox( - (profileId == NO_PROFILE_ID) ? dao.lookupByNameSync(String.valueOf(constraint) - .toUpperCase()) - : dao.lookupInProfileByNameSync(profileId, - String.valueOf(constraint) - .toUpperCase())); + (profileId == NO_PROFILE_ID) ? dao.lookupNamesByNameSync( + String.valueOf(constraint) + .toUpperCase()) : dao.lookupNamesInProfileByNameSync(profileId, + String.valueOf(constraint) + .toUpperCase())); results.values = matches; results.count = matches.size(); diff --git a/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmounts.java b/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmounts.java index 499a2b9c..86742ca2 100644 --- a/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmounts.java +++ b/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmounts.java @@ -17,6 +17,7 @@ package net.ktnx.mobileledger.db; +import androidx.annotation.NonNull; import androidx.room.Embedded; import androidx.room.Relation; @@ -27,4 +28,9 @@ public class AccountWithAmounts { public Account account; @Relation(parentColumn = "id", entityColumn = "account_id") public List amounts; + @NonNull + @Override + public String toString() { + return account.getName(); + } } diff --git a/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmountsAutocompleteAdapter.java b/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmountsAutocompleteAdapter.java new file mode 100644 index 00000000..e99df9ff --- /dev/null +++ b/app/src/main/java/net/ktnx/mobileledger/db/AccountWithAmountsAutocompleteAdapter.java @@ -0,0 +1,109 @@ +/* + * Copyright © 2021 Damyan Ivanov. + * This file is part of MoLe. + * MoLe is free software: you can distribute it and/or modify it + * under the term of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your opinion), any later version. + * + * MoLe is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License terms for details. + * + * You should have received a copy of the GNU General Public License + * along with MoLe. If not, see . + */ + +package net.ktnx.mobileledger.db; + +import android.content.Context; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; +import android.widget.Filter; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import net.ktnx.mobileledger.R; +import net.ktnx.mobileledger.dao.AccountDAO; +import net.ktnx.mobileledger.model.Data; +import net.ktnx.mobileledger.utils.Logger; +import net.ktnx.mobileledger.utils.Misc; + +import java.util.List; + +public class AccountWithAmountsAutocompleteAdapter extends ArrayAdapter { + private final AccountFilter filter = new AccountFilter(); + private final long profileId; + public AccountWithAmountsAutocompleteAdapter(Context context, @NonNull Profile profile) { + super(context, R.layout.account_autocomplete_row); + profileId = profile.getId(); + } + @NonNull + @Override + public Filter getFilter() { + return filter; + } + @NonNull + @Override + public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) { + View view = convertView; + if (view == null) { + view = LayoutInflater.from(parent.getContext()) + .inflate(R.layout.account_autocomplete_row, parent, false); + } + AccountWithAmounts item = getItem(position); + ((TextView) view.findViewById(R.id.account_name)).setText(item.account.getName()); + StringBuilder amountsText = new StringBuilder(); + for (AccountValue amt : item.amounts) { + if (amountsText.length() != 0) + amountsText.append('\n'); + String currency = amt.getCurrency(); + if (Misc.emptyIsNull(currency) != null) + amountsText.append(currency) + .append(' '); + amountsText.append(Data.formatNumber(amt.getValue())); + } + ((TextView) view.findViewById(R.id.amounts)).setText(amountsText.toString()); + + return view; + } + class AccountFilter extends Filter { + private final AccountDAO dao = DB.get() + .getAccountDAO(); + @Override + protected FilterResults performFiltering(CharSequence constraint) { + FilterResults results = new FilterResults(); + if (constraint == null) { + results.count = 0; + return results; + } + + Logger.debug("acc", String.format("Looking for account '%s'", constraint)); + final List matches = + dao.lookupWithAmountsInProfileByNameSync(profileId, String.valueOf(constraint) + .toUpperCase()); + results.values = matches; + results.count = matches.size(); + + return results; + } + @Override + @SuppressWarnings("unchecked") + protected void publishResults(CharSequence constraint, FilterResults results) { + if (results.values == null) { + notifyDataSetInvalidated(); + } + else { + setNotifyOnChange(false); + clear(); + addAll((List) results.values); + notifyDataSetChanged(); + } + } + } +} diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java index 7039f53a..229789e2 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/new_transaction/NewTransactionAccountRowItemHolder.java @@ -35,7 +35,7 @@ import androidx.recyclerview.widget.RecyclerView; import net.ktnx.mobileledger.R; import net.ktnx.mobileledger.databinding.NewTransactionAccountRowBinding; -import net.ktnx.mobileledger.db.AccountAutocompleteAdapter; +import net.ktnx.mobileledger.db.AccountWithAmountsAutocompleteAdapter; import net.ktnx.mobileledger.model.Currency; import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.ui.CurrencySelectorFragment; @@ -125,8 +125,9 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { NewTransactionActivity activity = (NewTransactionActivity) b.getRoot() .getContext(); - b.accountRowAccName.setAdapter(new AccountAutocompleteAdapter(b.getRoot() - .getContext(), mProfile)); + b.accountRowAccName.setAdapter(new AccountWithAmountsAutocompleteAdapter(b.getRoot() + .getContext(), + mProfile)); decimalSeparator = ""; Data.locale.observe(activity, locale -> decimalSeparator = String.valueOf( @@ -497,8 +498,8 @@ class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder { presentAccountName, incomingAccountName, acc.getAccountNameCursorPosition())); // avoid triggering completion pop-up - AccountAutocompleteAdapter a = - (AccountAutocompleteAdapter) b.accountRowAccName.getAdapter(); + AccountWithAmountsAutocompleteAdapter a = + (AccountWithAmountsAutocompleteAdapter) b.accountRowAccName.getAdapter(); try { b.accountRowAccName.setAdapter(null); b.accountRowAccName.setText(incomingAccountName); diff --git a/app/src/main/res/layout/account_autocomplete_row.xml b/app/src/main/res/layout/account_autocomplete_row.xml new file mode 100644 index 00000000..19ea3533 --- /dev/null +++ b/app/src/main/res/layout/account_autocomplete_row.xml @@ -0,0 +1,50 @@ + + + + + + + \ No newline at end of file -- 2.39.2