/*
- * Copyright © 2019 Damyan Ivanov.
+ * Copyright © 2020 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
import net.ktnx.mobileledger.model.Data;
import net.ktnx.mobileledger.model.LedgerTransactionAccount;
import net.ktnx.mobileledger.model.MobileLedgerProfile;
+import net.ktnx.mobileledger.utils.Globals;
+import net.ktnx.mobileledger.utils.SimpleDate;
import org.jetbrains.annotations.NotNull;
+import java.text.ParseException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
-import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
public class NewTransactionModel extends ViewModel {
- 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<Boolean> showCurrency = new MutableLiveData<>(false);
final ArrayList<Item> items = new ArrayList<>();
final MutableLiveData<Boolean> isSubmittable = new MutableLiveData<>(false);
+ final MutableLiveData<Boolean> showComments = new MutableLiveData<>(true);
private final Item header = new Item(this, null, "");
private final Item trailer = new Item(this);
private final MutableLiveData<Integer> focusedItem = new MutableLiveData<>(0);
private final MutableLiveData<Integer> accountCount = new MutableLiveData<>(0);
private final MutableLiveData<Boolean> simulateSave = new MutableLiveData<>(false);
- private boolean observingDataProfile;
- private Observer<MobileLedgerProfile> profileObserver =
- profile -> showCurrency.postValue(profile.getShowCommodityByDefault());
private final AtomicInteger busyCounter = new AtomicInteger(0);
private final MutableLiveData<Boolean> busyFlag = new MutableLiveData<>(false);
- final MutableLiveData<Boolean> showComments = new MutableLiveData<>(false);
+ private boolean observingDataProfile;
+ private Observer<MobileLedgerProfile> profileObserver = profile -> {
+ showCurrency.postValue(profile.getShowCommodityByDefault());
+ showComments.postValue(profile.getShowCommentsByDefault());
+ };
void observeShowComments(LifecycleOwner owner, Observer<? super Boolean> observer) {
showComments.observe(owner, observer);
}
int getAccountCount() {
return items.size();
}
- public Date getDate() {
+ public SimpleDate getDate() {
return header.date.getValue();
}
public String getDescription() {
return header.description.getValue();
}
+ public String getComment() {
+ return header.comment.getValue();
+ }
LiveData<Boolean> isSubmittable() {
return this.isSubmittable;
}
void reset() {
header.date.setValue(null);
header.description.setValue(null);
+ header.comment.setValue(null);
items.clear();
items.add(new Item(this, new LedgerTransactionAccount("")));
items.add(new Item(this, new LedgerTransactionAccount("")));
}
void incrementBusyCounter() {
int newValue = busyCounter.incrementAndGet();
- if (newValue == 1) busyFlag.postValue(true);
+ if (newValue == 1)
+ busyFlag.postValue(true);
}
void decrementBusyCounter() {
int newValue = busyCounter.decrementAndGet();
- if (newValue == 0) busyFlag.postValue(false);
+ if (newValue == 0)
+ busyFlag.postValue(false);
}
public boolean getBusyFlag() {
return busyFlag.getValue();
}
enum ItemType {generalData, transactionRow, bottomFiller}
- enum FocusedElement {Account, Comment, Amount}
+ enum FocusedElement {Account, Comment, Amount, Description, TransactionComment}
//==========================================================================================
static class Item {
private ItemType type;
- private MutableLiveData<Date> date = new MutableLiveData<>();
+ private MutableLiveData<SimpleDate> date = new MutableLiveData<>();
private MutableLiveData<String> description = new MutableLiveData<>();
private LedgerTransactionAccount account;
private MutableLiveData<String> amountHint = new MutableLiveData<>(null);
private FocusedElement focusedElement = FocusedElement.Account;
private MutableLiveData<String> comment = new MutableLiveData<>(null);
private MutableLiveData<Currency> currency = new MutableLiveData<>(null);
+ private MutableLiveData<Boolean> amountValid = new MutableLiveData<>(true);
private boolean amountHintIsSet = false;
Item(NewTransactionModel model) {
this.model = model;
type = ItemType.bottomFiller;
editable.setValue(false);
}
- Item(NewTransactionModel model, Date date, String description) {
+ Item(NewTransactionModel model, SimpleDate date, String description) {
this.model = model;
this.type = ItemType.generalData;
this.date.setValue(date);
wantedType));
}
}
- public Date getDate() {
+ public SimpleDate getDate() {
ensureType(ItemType.generalData);
return date.getValue();
}
- public void setDate(Date date) {
+ public void setDate(SimpleDate date) {
ensureType(ItemType.generalData);
this.date.setValue(date);
}
- public void setDate(String text) {
+ public void setDate(String text) throws ParseException {
if ((text == null) || text.trim()
.isEmpty())
{
- setDate((Date) null);
+ setDate((SimpleDate) null);
return;
}
- int year, month, day;
- final Calendar c = GregorianCalendar.getInstance();
- Matcher m = reYMD.matcher(text);
- if (m.matches()) {
- year = Integer.parseInt(m.group(1));
- month = Integer.parseInt(m.group(2)) - 1; // month is 0-based
- day = Integer.parseInt(m.group(3));
- }
- else {
- year = c.get(Calendar.YEAR);
- m = reMD.matcher(text);
- if (m.matches()) {
- month = Integer.parseInt(m.group(1)) - 1;
- day = Integer.parseInt(m.group(2));
- }
- else {
- month = c.get(Calendar.MONTH);
- m = reD.matcher(text);
- if (m.matches()) {
- day = Integer.parseInt(m.group(1));
- }
- else {
- day = c.get(Calendar.DAY_OF_MONTH);
- }
- }
- }
-
- c.set(year, month, day);
-
- this.setDate(c.getTime());
+ SimpleDate date = Globals.parseLedgerDate(text);
+ this.setDate(date);
}
void observeDate(@NonNull @NotNull androidx.lifecycle.LifecycleOwner owner,
- @NonNull androidx.lifecycle.Observer<? super Date> observer) {
+ @NonNull androidx.lifecycle.Observer<? super SimpleDate> observer) {
this.date.observe(owner, observer);
}
- void stopObservingDate(@NonNull androidx.lifecycle.Observer<? super Date> observer) {
+ void stopObservingDate(@NonNull androidx.lifecycle.Observer<? super SimpleDate> observer) {
this.date.removeObserver(observer);
}
public String getDescription() {
@NonNull androidx.lifecycle.Observer<? super String> observer) {
this.description.removeObserver(observer);
}
+ public String getTransactionComment() {
+ ensureType(ItemType.generalData);
+ return comment.getValue();
+ }
+ public void setTransactionComment(String transactionComment) {
+ ensureType(ItemType.generalData);
+ this.comment.setValue(transactionComment);
+ }
+ void observeTransactionComment(@NonNull @NotNull LifecycleOwner owner,
+ @NonNull Observer<? super String> observer) {
+ ensureType(ItemType.generalData);
+ this.comment.observe(owner, observer);
+ }
+ void stopObservingTransactionComment(@NonNull Observer<? super String> observer) {
+ this.comment.removeObserver(observer);
+ }
public LedgerTransactionAccount getAccount() {
ensureType(ItemType.transactionRow);
return account;
String getFormattedDate() {
if (date == null)
return null;
- Date time = date.getValue();
- if (time == null)
+ SimpleDate d = date.getValue();
+ if (d == null)
return null;
- Calendar c = GregorianCalendar.getInstance();
- c.setTime(time);
Calendar today = GregorianCalendar.getInstance();
- final int myYear = c.get(Calendar.YEAR);
- final int myMonth = c.get(Calendar.MONTH);
- final int myDay = c.get(Calendar.DAY_OF_MONTH);
-
- if (today.get(Calendar.YEAR) != myYear) {
- return String.format(Locale.US, "%d/%02d/%02d", myYear, myMonth + 1, myDay);
+ if (today.get(Calendar.YEAR) != d.year) {
+ return String.format(Locale.US, "%d/%02d/%02d", d.year, d.month, d.day);
}
- if (today.get(Calendar.MONTH) != myMonth) {
- return String.format(Locale.US, "%d/%02d", myMonth + 1, myDay);
+ if (today.get(Calendar.MONTH) != d.month - 1) {
+ return String.format(Locale.US, "%d/%02d", d.month, d.day);
}
- return String.valueOf(myDay);
+ return String.valueOf(d.day);
}
void observeEditableFlag(NewTransactionActivity activity, Observer<Boolean> observer) {
editable.observe(activity, observer);
boolean isAmountHintSet() {
return amountHintIsSet;
}
+ void validateAmount() {
+ amountValid.setValue(true);
+ }
+ void invalidateAmount() {
+ amountValid.setValue(false);
+ }
+ void observeAmountValidity(NewTransactionActivity activity, Observer<Boolean> observer) {
+ amountValid.observe(activity, observer);
+ }
+ void stopObservingAmountValidity(Observer<Boolean> observer) {
+ amountValid.removeObserver(observer);
+ }
}
}