X-Git-Url: https://git.ktnx.net/?a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fnet%2Fktnx%2Fmobileledger%2Fui%2Factivity%2FNewTransactionModel.java;h=9f5cd8c49108e622e288da4d066ad35e8e510bb4;hb=1f0ccbf96f45e2a99fe519fd6e32e9705729664f;hp=6dd640f9d8d22d505811f309dc0bd1b733979488;hpb=5f09bee380291c06a5fee1bb55049a1b09cf4e3c;p=mobile-ledger.git diff --git a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionModel.java b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionModel.java index 6dd640f9..9f5cd8c4 100644 --- a/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionModel.java +++ b/app/src/main/java/net/ktnx/mobileledger/ui/activity/NewTransactionModel.java @@ -20,13 +20,18 @@ package net.ktnx.mobileledger.ui.activity; import android.annotation.SuppressLint; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.Observer; import androidx.lifecycle.ViewModel; import net.ktnx.mobileledger.BuildConfig; +import net.ktnx.mobileledger.model.Currency; +import net.ktnx.mobileledger.model.Data; import net.ktnx.mobileledger.model.LedgerTransactionAccount; +import net.ktnx.mobileledger.model.MobileLedgerProfile; import net.ktnx.mobileledger.utils.Logger; import net.ktnx.mobileledger.utils.Misc; @@ -37,17 +42,21 @@ import java.util.Calendar; import java.util.Collections; import java.util.Date; import java.util.GregorianCalendar; +import java.util.HashMap; import java.util.List; import java.util.Locale; +import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import static net.ktnx.mobileledger.utils.Logger.debug; public class NewTransactionModel extends ViewModel { - static final Pattern reYMD = Pattern.compile("^\\s*(\\d+)\\d*/\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$"); - static final Pattern reMD = Pattern.compile("^\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$"); - static final Pattern reD = Pattern.compile("\\s*(\\d+)\\s*$"); + private static final Pattern reYMD = + Pattern.compile("^\\s*(\\d+)\\d*/\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$"); + private static final Pattern reMD = Pattern.compile("^\\s*(\\d+)\\s*/\\s*(\\d+)\\s*$"); + private static final Pattern reD = Pattern.compile("\\s*(\\d+)\\s*$"); + final MutableLiveData showCurrency = new MutableLiveData<>(false); private final Item header = new Item(this, null, ""); private final Item trailer = new Item(this); private final ArrayList items = new ArrayList<>(); @@ -55,21 +64,40 @@ public class NewTransactionModel extends ViewModel { private final MutableLiveData focusedItem = new MutableLiveData<>(0); private final MutableLiveData accountCount = new MutableLiveData<>(0); private final MutableLiveData simulateSave = new MutableLiveData<>(false); - public boolean getSimulateSave() { + /* + Slots contain lists of items, all using the same currency, including the possible + item with no account/amount that is used to help balancing the transaction + + There is one slot per currency + */ + private final HashMap> slots = new HashMap<>(); + private int checkHoldCounter = 0; + private Observer profileObserver = profile ->showCurrency.postValue(profile.getShowCommodityByDefault()); + public void observeDataProfile(LifecycleOwner activity) { + Data.profile.observe(activity, profileObserver); + } + void holdSubmittableChecks() { + checkHoldCounter++; + } + void releaseSubmittableChecks() { + if (checkHoldCounter == 0) + throw new RuntimeException("Asymmetrical call to releaseSubmittableChecks"); + checkHoldCounter--; + } + boolean getSimulateSave() { return simulateSave.getValue(); } public void setSimulateSave(boolean simulateSave) { this.simulateSave.setValue(simulateSave); } - public void toggleSimulateSave() { + void toggleSimulateSave() { simulateSave.setValue(!simulateSave.getValue()); } - public void observeSimulateSave(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull - androidx.lifecycle.Observer observer) { + void observeSimulateSave(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.simulateSave.observe(owner, observer); } - public int getAccountCount() { + int getAccountCount() { return items.size(); } public Date getDate() { @@ -78,7 +106,7 @@ public class NewTransactionModel extends ViewModel { public String getDescription() { return header.description.getValue(); } - public LiveData isSubmittable() { + LiveData isSubmittable() { return this.isSubmittable; } void reset() { @@ -89,28 +117,25 @@ public class NewTransactionModel extends ViewModel { items.add(new Item(this, new LedgerTransactionAccount(""))); focusedItem.setValue(0); } - public void observeFocusedItem(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull androidx.lifecycle.Observer observer) { + void observeFocusedItem(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.focusedItem.observe(owner, observer); } - public void stopObservingFocusedItem( - @NonNull androidx.lifecycle.Observer observer) { + void stopObservingFocusedItem(@NonNull androidx.lifecycle.Observer observer) { this.focusedItem.removeObserver(observer); } - public void observeAccountCount(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull - androidx.lifecycle.Observer observer) { + void observeAccountCount(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.accountCount.observe(owner, observer); } - public void stopObservingAccountCount( - @NonNull androidx.lifecycle.Observer observer) { + void stopObservingAccountCount(@NonNull androidx.lifecycle.Observer observer) { this.accountCount.removeObserver(observer); } - public int getFocusedItem() { return focusedItem.getValue(); } - public void setFocusedItem(int position) { + int getFocusedItem() { return focusedItem.getValue(); } + void setFocusedItem(int position) { focusedItem.setValue(position); } - public int addAccount(LedgerTransactionAccount acc) { + int addAccount(LedgerTransactionAccount acc) { items.add(new Item(this, acc)); accountCount.setValue(getAccountCount()); return items.size(); @@ -132,7 +157,7 @@ public class NewTransactionModel extends ViewModel { return items.get(index) .getAccount(); } - public Item getItem(int index) { + Item getItem(int index) { if (index == 0) { return header; } @@ -146,22 +171,33 @@ public class NewTransactionModel extends ViewModel { A transaction is submittable if: 0) has description 1) has at least two account names - 2) each amount has account name - 3) amounts must balance to 0, or - 3a) there must be exactly one empty amount (with account) + 2) each row with amount has account name + 3) for each commodity: + 3a) amounts must balance to 0, or + 3b) there must be exactly one empty amount (with account) 4) empty accounts with empty amounts are ignored - 5) a row with an empty account name or empty amount is guaranteed to exist + Side effects: + 5) a row with an empty account name or empty amount is guaranteed to exist for each commodity + 6) at least two rows need to be present in the ledger + */ @SuppressLint("DefaultLocale") - public void checkTransactionSubmittable(NewTransactionItemsAdapter adapter) { + void checkTransactionSubmittable(NewTransactionItemsAdapter adapter) { + if (checkHoldCounter > 0) + return; + int accounts = 0; - int amounts = 0; - int empty_rows = 0; - float balance = 0f; + final BalanceForCurrency balance = new BalanceForCurrency(); final String descriptionText = getDescription(); boolean submittable = true; - List itemsWithEmptyAmount = new ArrayList<>(); - List itemsWithAccountAndEmptyAmount = new ArrayList<>(); + final ItemsForCurrency itemsForCurrency = new ItemsForCurrency(); + final ItemsForCurrency itemsWithEmptyAmountForCurrency = new ItemsForCurrency(); + final ItemsForCurrency itemsWithAccountAndEmptyAmountForCurrency = new ItemsForCurrency(); + final ItemsForCurrency itemsWithEmptyAccountForCurrency = new ItemsForCurrency(); + final ItemsForCurrency itemsWithAmountForCurrency = new ItemsForCurrency(); + final ItemsForCurrency itemsWithAccountForCurrency = new ItemsForCurrency(); + final ItemsForCurrency emptyRowsForCurrency = new ItemsForCurrency(); + final List emptyRows = new ArrayList<>(); try { if ((descriptionText == null) || descriptionText.trim() @@ -177,84 +213,174 @@ public class NewTransactionModel extends ViewModel { LedgerTransactionAccount acc = item.getAccount(); String acc_name = acc.getAccountName() .trim(); + String currName = acc.getCurrency(); + + itemsForCurrency.add(currName, item); + if (acc_name.isEmpty()) { - empty_rows++; + itemsWithEmptyAccountForCurrency.add(currName, item); if (acc.isAmountSet()) { // 2) each amount has account name Logger.debug("submittable", String.format( - "Transaction not submittable: row %d has no account name, but has" + - " amount %1.2f", i + 1, acc.getAmount())); + "Transaction not submittable: row %d has no account name, but" + + " has" + " amount %1.2f", i + 1, acc.getAmount())); submittable = false; } + else { + emptyRowsForCurrency.add(currName, item); + } } else { accounts++; + itemsWithAccountForCurrency.add(currName, item); } if (acc.isAmountSet()) { - amounts++; - balance += acc.getAmount(); + itemsWithAmountForCurrency.add(currName, item); + balance.add(currName, acc.getAmount()); } else { - itemsWithEmptyAmount.add(item); + itemsWithEmptyAmountForCurrency.add(currName, item); - if (!acc_name.isEmpty()) { - itemsWithAccountAndEmptyAmount.add(item); - } + if (!acc_name.isEmpty()) + itemsWithAccountAndEmptyAmountForCurrency.add(currName, item); } } // 1) has at least two account names if (accounts < 2) { - Logger.debug("submittable", - String.format("Transaction not submittable: only %d account names", - accounts)); + if (accounts == 0) + Logger.debug("submittable", + "Transaction not submittable: no account " + "names"); + else if (accounts == 1) + Logger.debug("submittable", + "Transaction not submittable: only one account name"); + else + Logger.debug("submittable", + String.format("Transaction not submittable: only %d account names", + accounts)); submittable = false; } - // 3) amount must balance to 0, or - // 3a) there must be exactly one empty amount (with account) - if (Misc.isZero(balance)) { - for (Item item : items) { - item.setAmountHint(null); + // 3) for each commodity: + // 3a) amount must balance to 0, or + // 3b) there must be exactly one empty amount (with account) + for (String balCurrency : itemsForCurrency.currencies()) { + float currencyBalance = balance.get(balCurrency); + if (Misc.isZero(currencyBalance)) { + // remove hints from all amount inputs in that currency + for (Item item : items) { + if (Currency.equal(item.getCurrency(), balCurrency)) + item.setAmountHint(null); + } + } + else { + List list = + itemsWithAccountAndEmptyAmountForCurrency.getList(balCurrency); + int balanceReceiversCount = list.size(); + if (balanceReceiversCount != 1) { + if (BuildConfig.DEBUG) { + if (balanceReceiversCount == 0) + Logger.debug("submittable", String.format( + "Transaction not submittable [%s]: non-zero balance " + + "with no empty amounts with accounts", balCurrency)); + else + Logger.debug("submittable", String.format( + "Transaction not submittable [%s]: non-zero balance " + + "with multiple empty amounts with accounts", balCurrency)); + } + submittable = false; + } + + List emptyAmountList = + itemsWithEmptyAmountForCurrency.getList(balCurrency); + + // suggest off-balance amount to a row and remove hints on other rows + Item receiver = null; + if (!list.isEmpty()) + receiver = list.get(0); + else if (!emptyAmountList.isEmpty()) + receiver = emptyAmountList.get(0); + + for (Item item : items) { + if (!Currency.equal(item.getCurrency(), balCurrency)) + continue; + + if (item.equals(receiver)) { + if (BuildConfig.DEBUG) + Logger.debug("submittable", + String.format("Setting amount hint to %1.2f [%s]", + -currencyBalance, balCurrency)); + item.setAmountHint(String.format("%1.2f", -currencyBalance)); + } + else { + if (BuildConfig.DEBUG) + Logger.debug("submittable", + String.format("Resetting hint of '%s' [%s]", + (item.getAccount() == null) ? "" : item.getAccount() + .getAccountName(), + balCurrency)); + item.setAmountHint(null); + } + } + } + } + + // 5) a row with an empty account name or empty amount is guaranteed to exist for + // each commodity + for (String balCurrency : balance.currencies()) { + int currEmptyRows = itemsWithEmptyAccountForCurrency.size(balCurrency); + int currRows = itemsForCurrency.size(balCurrency); + int currAccounts = itemsWithAccountForCurrency.size(balCurrency); + int currAmounts = itemsWithAmountForCurrency.size(balCurrency); + if ((currEmptyRows == 0) && + ((currRows == currAccounts) || (currRows == currAmounts))) + { + // perhaps there already is an unused empty row for another currency that + // is not used? +// boolean foundIt = false; +// for (Item item : emptyRows) { +// Currency itemCurrency = item.getCurrency(); +// String itemCurrencyName = +// (itemCurrency == null) ? "" : itemCurrency.getName(); +// if (Misc.isZero(balance.get(itemCurrencyName))) { +// item.setCurrency(Currency.loadByName(balCurrency)); +// item.setAmountHint( +// String.format("%1.2f", -balance.get(balCurrency))); +// foundIt = true; +// break; +// } +// } +// +// if (!foundIt) + adapter.addRow(balCurrency); } } - else { - int balanceReceiversCount = itemsWithAccountAndEmptyAmount.size(); - if (balanceReceiversCount != 1) { - Logger.debug("submittable", (balanceReceiversCount == 0) ? - "Transaction not submittable: non-zero balance " + - "with no empty amounts with accounts" : - "Transaction not submittable: non-zero balance " + - "with multiple empty amounts with accounts"); - submittable = false; + + // drop extra empty rows, not needed + for (String currName : emptyRowsForCurrency.currencies()) { + List emptyItems = emptyRowsForCurrency.getList(currName); + while ((this.items.size() > 2) && (emptyItems.size() > 1)) { + Item item = emptyItems.get(1); + emptyItems.remove(1); + removeRow(item, adapter); } - // suggest off-balance amount to a row and remove hints on other rows - Item receiver = null; - if (!itemsWithAccountAndEmptyAmount.isEmpty()) - receiver = itemsWithAccountAndEmptyAmount.get(0); - else if (!itemsWithEmptyAmount.isEmpty()) - receiver = itemsWithEmptyAmount.get(0); - - for (Item item : items) { - if (item.equals(receiver)) { - Logger.debug("submittable", - String.format("Setting amount hint to %1.2f", -balance)); - item.setAmountHint(String.format("%1.2f", -balance)); + // unused currency, remove last item (which is also an empty one) + if ((items.size() > 2) && (emptyItems.size() == 1)) { + List currItems = itemsForCurrency.getList(currName); + + if (currItems.size() == 1) { + Item item = emptyItems.get(0); + removeRow(item, adapter); } - else - item.setAmountHint(null); } } - // 5) a row with an empty account name or empty amount is guaranteed to exist - if ((empty_rows == 0) && - ((this.items.size() == accounts) || (this.items.size() == amounts))) - { + // 6) at least two rows need to be present in the ledger + while (this.items.size() < 2) adapter.addRow(); - } debug("submittable", submittable ? "YES" : "NO"); @@ -265,9 +391,10 @@ public class NewTransactionModel extends ViewModel { for (int i = 0; i < items.size(); i++) { Item item = items.get(i); LedgerTransactionAccount acc = item.getAccount(); - debug("submittable", String.format("Item %2d: [%4.2f] %s (%s)", i, - acc.isAmountSet() ? acc.getAmount() : 0, acc.getAccountName(), - acc.getComment())); + debug("submittable", String.format("Item %2d: [%4.2f(%s) %s] %s ; %s", i, + acc.isAmountSet() ? acc.getAmount() : 0, + item.isAmountHintSet() ? item.getAmountHint() : "ø", acc.getCurrency(), + acc.getAccountName(), acc.getComment())); } } } @@ -281,34 +408,121 @@ public class NewTransactionModel extends ViewModel { isSubmittable.setValue(false); } } - public void removeItem(int pos) { + private void removeRow(Item item, NewTransactionItemsAdapter adapter) { + int pos = items.indexOf(item); + items.remove(pos); + if (adapter != null) { + adapter.notifyItemRemoved(pos + 1); + sendCountNotifications(); + } + } + void removeItem(int pos) { items.remove(pos); accountCount.setValue(getAccountCount()); } - public void sendCountNotifications() { + void sendCountNotifications() { accountCount.setValue(getAccountCount()); } public void sendFocusedNotification() { focusedItem.setValue(focusedItem.getValue()); } - public void updateFocusedItem(int position) { + void updateFocusedItem(int position) { focusedItem.setValue(position); } - public void noteFocusChanged(int position, FocusedElement element) { + void noteFocusChanged(int position, FocusedElement element) { getItem(position).setFocusedElement(element); } - public void swapItems(int one, int two) { - Collections.swap(items, one-1, two-1); + void swapItems(int one, int two) { + Collections.swap(items, one - 1, two - 1); } - public void toggleComment(int position) { + void toggleComment(int position) { final MutableLiveData commentVisible = getItem(position).commentVisible; commentVisible.postValue(!commentVisible.getValue()); } + void moveItemLast(int index) { + /* 0 + 1 <-- index + 2 + 3 <-- desired position + */ + int itemCount = items.size(); + + if (index < itemCount - 1) { + Item acc = items.remove(index); + items.add(itemCount - 1, acc); + } + } + void toggleCurrencyVisible() { + showCurrency.setValue(!showCurrency.getValue()); + } + public void setItemCurrency(Item item, Currency newCurrency, + NewTransactionItemsAdapter adapter) { + Currency oldCurrency = item.getCurrency(); + if (!Currency.equal(newCurrency, oldCurrency)) { + holdSubmittableChecks(); + try { + item.setCurrency(newCurrency); +// for (Item i : items) { +// if (Currency.equal(i.getCurrency(), oldCurrency)) +// i.setCurrency(newCurrency); +// } + } + finally { + releaseSubmittableChecks(); + } + + checkTransactionSubmittable(adapter); + } + } enum ItemType {generalData, transactionRow, bottomFiller} + enum FocusedElement {Account, Comment, Amount} + + private class ItemsForCurrency { + private HashMap> hashMap = new HashMap<>(); + @NonNull + List getList(@Nullable String currencyName) { + List list = hashMap.get(currencyName); + if (list == null) { + list = new ArrayList<>(); + hashMap.put(currencyName, list); + } + return list; + } + void add(@Nullable String currencyName, @NonNull Item item) { + getList(currencyName).add(item); + } + int size(@Nullable String currencyName) { + return this.getList(currencyName) + .size(); + } + Set currencies() { + return hashMap.keySet(); + } + } + //========================================================================================== - enum FocusedElement {Account, Comment, Amount} + private class BalanceForCurrency { + private HashMap hashMap = new HashMap<>(); + float get(String currencyName) { + Float f = hashMap.get(currencyName); + if (f == null) { + f = 0f; + hashMap.put(currencyName, f); + } + return f; + } + void add(String currencyName, float amount) { + hashMap.put(currencyName, get(currencyName) + amount); + } + Set currencies() { + return hashMap.keySet(); + } + boolean containsCurrency(String currencyName) { + return hashMap.containsKey(currencyName); + } + } class Item { private ItemType type; @@ -321,34 +535,41 @@ public class NewTransactionModel extends ViewModel { private FocusedElement focusedElement = FocusedElement.Account; private MutableLiveData comment = new MutableLiveData<>(null); private MutableLiveData commentVisible = new MutableLiveData<>(false); - public Item(NewTransactionModel model) { + private MutableLiveData currency = new MutableLiveData<>(null); + private boolean amountHintIsSet = false; + Item(NewTransactionModel model) { this.model = model; type = ItemType.bottomFiller; editable.setValue(false); } - public Item(NewTransactionModel model, Date date, String description) { + Item(NewTransactionModel model, Date date, String description) { this.model = model; this.type = ItemType.generalData; this.date.setValue(date); this.description.setValue(description); this.editable.setValue(true); } - public Item(NewTransactionModel model, LedgerTransactionAccount account) { + Item(NewTransactionModel model, LedgerTransactionAccount account) { this.model = model; this.type = ItemType.transactionRow; this.account = account; + String currName = account.getCurrency(); + Currency curr = null; + if ((currName != null) && !currName.isEmpty()) + curr = Currency.loadByName(currName); + this.currency.setValue(curr); this.editable.setValue(true); } - public FocusedElement getFocusedElement() { + FocusedElement getFocusedElement() { return focusedElement; } - public void setFocusedElement(FocusedElement focusedElement) { + void setFocusedElement(FocusedElement focusedElement) { this.focusedElement = focusedElement; } public NewTransactionModel getModel() { return model; } - public void setEditable(boolean editable) { + void setEditable(boolean editable) { ensureType(ItemType.generalData, ItemType.transactionRow); this.editable.setValue(editable); } @@ -359,38 +580,39 @@ public class NewTransactionModel extends ViewModel { type1, type2)); } } - public String getAmountHint() { + String getAmountHint() { ensureType(ItemType.transactionRow); return amountHint.getValue(); } - public void setAmountHint(String amountHint) { + void setAmountHint(String amountHint) { ensureType(ItemType.transactionRow); // avoid unnecessary triggers if (amountHint == null) { if (this.amountHint.getValue() == null) return; + amountHintIsSet = false; } else { if (amountHint.equals(this.amountHint.getValue())) return; + amountHintIsSet = true; } this.amountHint.setValue(amountHint); } - public void observeAmountHint(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull - androidx.lifecycle.Observer observer) { + void observeAmountHint(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.amountHint.observe(owner, observer); } - public void stopObservingAmountHint( + void stopObservingAmountHint( @NonNull androidx.lifecycle.Observer observer) { this.amountHint.removeObserver(observer); } - public ItemType getType() { + ItemType getType() { return type; } - public void ensureType(ItemType wantedType) { + void ensureType(ItemType wantedType) { if (type != wantedType) { throw new RuntimeException( String.format("Actual type (%s) differs from wanted (%s)", type, @@ -444,11 +666,11 @@ public class NewTransactionModel extends ViewModel { this.setDate(c.getTime()); } - public void observeDate(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull androidx.lifecycle.Observer observer) { + void observeDate(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.date.observe(owner, observer); } - public void stopObservingDate(@NonNull androidx.lifecycle.Observer observer) { + void stopObservingDate(@NonNull androidx.lifecycle.Observer observer) { this.date.removeObserver(observer); } public String getDescription() { @@ -459,12 +681,11 @@ public class NewTransactionModel extends ViewModel { ensureType(ItemType.generalData); this.description.setValue(description); } - public void observeDescription(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, - @NonNull - androidx.lifecycle.Observer observer) { + void observeDescription(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner, + @NonNull androidx.lifecycle.Observer observer) { this.description.observe(owner, observer); } - public void stopObservingDescription( + void stopObservingDescription( @NonNull androidx.lifecycle.Observer observer) { this.description.removeObserver(observer); } @@ -480,7 +701,7 @@ public class NewTransactionModel extends ViewModel { * * @return nicely formatted, shortest available date representation */ - public String getFormattedDate() { + String getFormattedDate() { if (date == null) return null; Date time = date.getValue(); @@ -505,30 +726,53 @@ public class NewTransactionModel extends ViewModel { return String.valueOf(myDay); } - public void observeEditableFlag(NewTransactionActivity activity, - Observer observer) { + void observeEditableFlag(NewTransactionActivity activity, Observer observer) { editable.observe(activity, observer); } - public void stopObservingEditableFlag(Observer observer) { + void stopObservingEditableFlag(Observer observer) { editable.removeObserver(observer); } - public void observeCommentVisible(NewTransactionActivity activity, - Observer observer) { + void observeCommentVisible(NewTransactionActivity activity, Observer observer) { commentVisible.observe(activity, observer); } - public void stopObservingCommentVisible(Observer observer) { + void stopObservingCommentVisible(Observer observer) { commentVisible.removeObserver(observer); } - public void observeComment(NewTransactionActivity activity, - Observer observer) { + void observeComment(NewTransactionActivity activity, Observer observer) { comment.observe(activity, observer); } - public void stopObservingComment(Observer observer) { + void stopObservingComment(Observer observer) { comment.removeObserver(observer); } public void setComment(String comment) { getAccount().setComment(comment); this.comment.postValue(comment); } + public Currency getCurrency() { + return this.currency.getValue(); + } + public void setCurrency(Currency currency) { + Currency present = this.currency.getValue(); + if ((currency == null) && (present != null) || + (currency != null) && !currency.equals(present)) + { + getAccount().setCurrency((currency != null && !currency.getName() + .isEmpty()) + ? currency.getName() : null); + this.currency.setValue(currency); + } + } + void observeCurrency(NewTransactionActivity activity, Observer observer) { + currency.observe(activity, observer); + } + void stopObservingCurrency(Observer observer) { + currency.removeObserver(observer); + } + boolean isOfType(ItemType type) { + return this.type == type; + } + boolean isAmountHintSet() { + return amountHintIsSet; + } } }