import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.Misc;
-import java.text.DecimalFormatSymbols;
+import java.text.ParseException;
class NewTransactionAccountRowItemHolder extends NewTransactionItemViewHolder {
- private final String decimalDot = ".";
private final NewTransactionAccountRowBinding b;
private boolean ignoreFocusChanges = false;
- private String decimalSeparator;
private boolean inUpdate = false;
private boolean syncingData = false;
NewTransactionAccountRowItemHolder(@NonNull NewTransactionAccountRowBinding b,
if (id == R.id.account_row_acc_amounts) {
try {
String input = String.valueOf(b.accountRowAccAmounts.getText());
- input = input.replace(decimalSeparator, decimalDot);
- final String newText = String.format("%4.2f", Float.parseFloat(input));
+ input = input.replace(Data.getDecimalSeparator(), Data.decimalDot);
+ final String newText = Data.formatNumber(Float.parseFloat(input));
if (!newText.equals(input)) {
boolean wasSyncingData = syncingData;
syncingData = true;
try {
+ // FIXME this needs to reach the model somehow
b.accountRowAccAmounts.setText(newText);
}
finally {
.getContext(),
mProfile));
- decimalSeparator = "";
- Data.locale.observe(activity, locale -> decimalSeparator = String.valueOf(
- DecimalFormatSymbols.getInstance(locale)
- .getMonetaryDecimalSeparator()));
-
final TextWatcher tw = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
}
public void checkAmountValid(String s) {
+ // FIXME this needs to be done in the model only
boolean valid = true;
try {
if (s.length() > 0) {
- float ignored = Float.parseFloat(s.replace(decimalSeparator, decimalDot));
+ float ignored =
+ Float.parseFloat(s.replace(Data.getDecimalSeparator(), Data.decimalDot));
}
}
catch (NumberFormatException ex) {
- valid = false;
+ try {
+ float ignored = Data.parseNumber(s);
+ }
+ catch (ParseException ex2) {
+ valid = false;
+ }
}
displayAmountValidity(valid);
acc.setComment(String.valueOf(b.comment.getText()));
String amount = String.valueOf(b.accountRowAccAmounts.getText());
- amount = amount.trim();
- if (amount.isEmpty()) {
- if (acc.isAmountSet())
- significantChange = true;
- acc.resetAmount();
- acc.setAmountValid(true);
- }
- else {
- try {
- amount = amount.replace(decimalSeparator, decimalDot);
- final float parsedAmount = Float.parseFloat(amount);
- if (!acc.isAmountSet() || !Misc.equalFloats(parsedAmount, acc.getAmount()))
- significantChange = true;
- acc.setAmount(parsedAmount);
- acc.setAmountValid(true);
- }
- catch (NumberFormatException e) {
- Logger.debug("new-trans", String.format(
- "assuming amount is not set due to number format exception. " +
- "input was '%s'", amount));
- if (acc.isAmountValid())
- significantChange = true;
- acc.resetAmount();
- acc.setAmountValid(false);
- }
- final String curr = String.valueOf(b.currency.getText());
- final String currValue;
- if (curr.equals(b.currency.getContext()
- .getResources()
- .getString(R.string.currency_symbol)) || curr.isEmpty())
- currValue = null;
- else
- currValue = curr;
-
- if (!significantChange && !Misc.equalStrings(acc.getCurrency(), currValue))
- significantChange = true;
- acc.setCurrency(currValue);
- }
+ if (acc.setAndCheckAmountText(Misc.nullIsEmpty(amount)))
+ significantChange = true;
+ displayAmountValidity(!acc.isAmountSet() || acc.isAmountValid());
+
+ final String curr = String.valueOf(b.currency.getText());
+ final String currValue;
+ if (curr.equals(b.currency.getContext()
+ .getResources()
+ .getString(R.string.currency_symbol)) || curr.isEmpty())
+ currValue = null;
+ else
+ currValue = curr;
+
+ if (!significantChange && !Misc.equalStrings(acc.getCurrency(), currValue))
+ significantChange = true;
+ acc.setCurrency(currValue);
return significantChange;
}
acc.isLast() ? EditorInfo.IME_ACTION_DONE : EditorInfo.IME_ACTION_NEXT);
setCurrencyString(acc.getCurrency());
- b.accountRowAccAmounts.setText(
- acc.isAmountSet() ? String.format("%4.2f", acc.getAmount()) : null);
- displayAmountValidity(true);
+ b.accountRowAccAmounts.setText(acc.getAmountText());
+ displayAmountValidity(!acc.isAmountSet() || acc.isAmountValid());
final String comment = acc.getComment();
b.comment.setText(comment);
return copy;
}
private List<Item> shallowCopyList() {
- return new ArrayList<>(items.getValue());
+ return new ArrayList<>(Objects.requireNonNull(items.getValue()));
}
LiveData<Boolean> getShowComments() {
return showComments;
itemsWithAccountForCurrency.add(currName, item);
}
- if (item.isAmountSet()) {
+ if (item.isAmountSet() && item.isAmountValid()) {
itemsWithAmountForCurrency.add(currName, item);
balance.add(currName, item.getAmount());
}
else {
if (!item.isAmountValid()) {
Logger.debug("submittable",
- String.format("Not submittable: row %d has an invalid amount",
- i + 1));
+ String.format("Not submittable: row %d has an invalid amount", i));
submittable = false;
hasInvalidAmount = true;
}
continue;
if (item == receiver) {
- final String hint = String.format("%1.2f", -currencyBalance);
+ final String hint = Data.formatNumber(-currencyBalance);
if (!acc.isAmountHintSet() ||
!Misc.equalStrings(acc.getAmountHint(), hint))
{
// if (Misc.isZero(balance.get(itemCurrencyName))) {
// item.setCurrency(Currency.loadByName(balCurrency));
// item.setAmountHint(
-// String.format("%1.2f", -balance.get(balCurrency)));
+// Data.formatNumber(-balance.get(balCurrency)));
// foundIt = true;
// break;
// }
final TransactionAccount newAcc = new TransactionAccount("", balCurrency);
final float bal = balance.get(balCurrency);
if (!Misc.isZero(bal) && currAmounts == currRows)
- newAcc.setAmountHint(String.format("%4.2f", -bal));
+ newAcc.setAmountHint(Data.formatNumber(-bal));
Logger.debug("submittable",
String.format("Adding new item with %s for currency %s",
newAcc.getAmountHint(), balCurrency));
private float amount;
private boolean amountSet;
private boolean amountValid = true;
+ @NotNull
+ private String amountText = "";
private FocusedElement focusedElement = FocusedElement.Account;
private boolean amountHintIsSet = false;
private boolean isLast = false;
amountSet = origin.amountSet;
amountHint = origin.amountHint;
amountHintIsSet = origin.amountHintIsSet;
+ amountText = origin.amountText;
comment = origin.comment;
currency = origin.currency;
amountValid = origin.amountValid;
isLast = origin.isLast;
accountNameCursorPosition = origin.accountNameCursorPosition;
}
- public TransactionAccount(LedgerTransactionAccount account) {
- super();
- currency = Misc.nullIsEmpty(account.getCurrency());
- amount = account.getAmount();
- }
public TransactionAccount(String accountName) {
super();
this.accountName = accountName;
this.accountName = accountName;
this.currency = currency;
}
+ public @NotNull String getAmountText() {
+ return amountText;
+ }
+ public void setAmountText(@NotNull String amountText) {
+ this.amountText = amountText;
+ }
+ public boolean setAndCheckAmountText(@NotNull String amountText) {
+ String amtText = amountText.trim();
+ this.amountText = amtText;
+
+ boolean significantChange = false;
+
+ if (amtText.isEmpty()) {
+ if (amountSet) {
+ significantChange = true;
+ }
+ resetAmount();
+ }
+ else {
+ try {
+ amtText = amtText.replace(Data.getDecimalSeparator(), Data.decimalDot);
+ final float parsedAmount = Float.parseFloat(amtText);
+ if (!amountSet || !amountValid || !Misc.equalFloats(parsedAmount, amount))
+ significantChange = true;
+ amount = parsedAmount;
+ amountSet = true;
+ amountValid = true;
+ }
+ catch (NumberFormatException e) {
+ Logger.debug("new-trans", String.format(
+ "assuming amount is not set due to number format exception. " +
+ "input was '%s'", amtText));
+ if (amountValid) // it was valid and now it's not
+ significantChange = true;
+ amountValid = false;
+ }
+ }
+
+ return significantChange;
+ }
public boolean isLast() {
return isLast;
}
public void setAmount(float amount) {
this.amount = amount;
amountSet = true;
+ amountValid = true;
+ amountText = Data.formatNumber(amount);
}
public void resetAmount() {
amountSet = false;
+ amountValid = true;
+ amountText = "";
}
@Override
public ItemType getType() {
b.append(String.format(" acc'%s'", accountName));
if (amountSet)
- b.append(String.format(" %4.2f", amount));
+ b.append(amountText)
+ .append(" [")
+ .append(amountValid ? "valid" : "invalid")
+ .append("] ")
+ .append(String.format(Locale.ROOT, " {raw %4.2f}", amount));
else if (amountHintIsSet)
- b.append(String.format(" (%s)", amountHint));
+ b.append(String.format(" (hint %s)", amountHint));
if (!TextUtils.isEmpty(currency))
b.append(" ")
boolean equal = Misc.equalStrings(accountName, other.accountName);
equal = equal && Misc.equalStrings(comment, other.comment) &&
- (amountSet ? other.amountSet && amount == other.amount : !other.amountSet);
+ (amountSet ? other.amountSet && amountValid == other.amountValid &&
+ Misc.equalStrings(amountText, other.amountText)
+ : !other.amountSet);
// compare amount hint only if there is no amount
if (!amountSet)