import androidx.annotation.NonNull;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
+import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModel;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
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 String ZERO_AMOUNT_HINT = "0.00";
private final Item header = new Item(this, null, "");
private final Item trailer = new Item(this);
private final ArrayList<Item> items = new ArrayList<>();
boolean accountsInInitialState() {
for (Item item : items) {
LedgerTransactionAccount acc = item.getAccount();
- if (acc.isAmountSet()) return false;
+ if (acc.isAmountSet())
+ return false;
if (!acc.getAccountName()
.trim()
- .isEmpty()) return false;
+ .isEmpty())
+ return false;
}
return true;
if (index == 0) {
return header;
}
- else if (index <= items.size()) return items.get(index - 1);
- else return trailer;
+
+ if (index <= items.size())
+ return items.get(index - 1);
+
+ return trailer;
}
// rules:
// 1) at least two account names
LedgerTransactionAccount acc = item.getAccount();
String acc_name = acc.getAccountName()
.trim();
- if (!acc_name.isEmpty()) {
+ if (acc_name.isEmpty()) {
+ empty_rows++;
+ }
+ else {
accounts++;
if (acc.isAmountSet()) {
accounts_with_values++;
}
}
- else empty_rows++;
- if (!acc.isAmountSet()) {
+ if (acc.isAmountSet()) {
+ amounts++;
+ if (!acc_name.isEmpty())
+ amounts_with_accounts++;
+ running_total += acc.getAmount();
+ }
+ else {
if (empty_amount == null) {
empty_amount = item;
single_empty_amount = true;
single_empty_amount_has_account = !acc_name.isEmpty();
}
- else if (!acc_name.isEmpty()) single_empty_amount = false;
- }
- else {
- amounts++;
- if (!acc_name.isEmpty()) amounts_with_accounts++;
- running_total += acc.getAmount();
+ else if (!acc_name.isEmpty())
+ single_empty_amount = false;
}
}
adapter.addRow();
}
- if (single_empty_amount) {
- empty_amount.setAmountHint(String.format(Locale.US, "%1.2f",
- Misc.isZero(running_total) ? 0f : -running_total));
+ for (NewTransactionModel.Item item : items) {
+
+ final LedgerTransactionAccount acc = item.getAccount();
+ if (acc.isAmountSet())
+ continue;
+
+ if (single_empty_amount) {
+ if (item.equals(empty_amount)) {
+ empty_amount.setAmountHint(String.format(Locale.US, "%1.2f",
+ Misc.isZero(running_total) ? 0f : -running_total));
+ continue;
+ }
+ }
+ else {
+ // no single empty account and this account's amount is not set
+ // => hint should be '0.00'
+ String hint = item.getAmountHint();
+ if ((hint == null) || !hint.equals(ZERO_AMOUNT_HINT)) {
+ item.setAmountHint(ZERO_AMOUNT_HINT);
+ }
+ }
+
}
debug("submittable", String.format(Locale.US,
private LedgerTransactionAccount account;
private MutableLiveData<String> amountHint = new MutableLiveData<>();
private NewTransactionModel model;
- private boolean editable = true;
+ private MutableLiveData<Boolean> editable = new MutableLiveData<>(true);
public Item(NewTransactionModel model) {
this.model = model;
type = ItemType.bottomFiller;
+ editable.setValue(false);
}
public 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) {
this.model = model;
this.type = ItemType.transactionRow;
this.account = account;
+ this.editable.setValue(true);
}
public NewTransactionModel getModel() {
return model;
}
public boolean isEditable() {
ensureType(ItemType.transactionRow);
- return editable;
+ return this.editable.getValue();
}
public void setEditable(boolean editable) {
ensureType(ItemType.transactionRow);
- this.editable = editable;
+ this.editable.setValue(editable);
}
public String getAmountHint() {
ensureType(ItemType.transactionRow);
public void ensureType(ItemType wantedType) {
if (type != wantedType) {
throw new RuntimeException(
- String.format("Actual type (%d) differs from wanted (%s)", type,
+ String.format("Actual type (%s) differs from wanted (%s)", type,
wantedType));
}
}
* @return nicely formatted, shortest available date representation
*/
public String getFormattedDate() {
- if (date == null) return null;
+ if (date == null)
+ return null;
Date time = date.getValue();
- if (time == null) return null;
+ if (time == null)
+ return null;
Calendar c = GregorianCalendar.getInstance();
c.setTime(time);
return String.valueOf(myDay);
}
+ public void observeEditableFlag(NewTransactionActivity activity,
+ Observer<Boolean> observer) {
+ editable.observe(activity, observer);
+ }
+ public void stopObservingEditableFlag(Observer<Boolean> observer) {
+ editable.removeObserver(observer);
+ }
}
}