import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import net.ktnx.mobileledger.App;
import net.ktnx.mobileledger.R;
import net.ktnx.mobileledger.async.DbOpQueue;
import net.ktnx.mobileledger.async.SendTransactionTask;
-import net.ktnx.mobileledger.utils.Globals;
import net.ktnx.mobileledger.utils.Logger;
import net.ktnx.mobileledger.utils.MLDB;
import net.ktnx.mobileledger.utils.Misc;
import java.util.ArrayList;
+import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
// N.B. when adding new fields, update the copy-constructor below
private FutureDates futureDates = FutureDates.None;
private SendTransactionTask.API apiVersion = SendTransactionTask.API.auto;
+ private Calendar firstTransactionDate;
+ private Calendar lastTransactionDate;
+ private MutableLiveData<ArrayList<LedgerAccount>> accounts =
+ new MutableLiveData<>(new ArrayList<>());
+ private AccountListLoader loader = null;
public MobileLedgerProfile() {
this.uuid = String.valueOf(UUID.randomUUID());
}
futureDates = origin.futureDates;
apiVersion = origin.apiVersion;
defaultCommodity = origin.defaultCommodity;
+ firstTransactionDate = origin.firstTransactionDate;
+ lastTransactionDate = origin.lastTransactionDate;
}
// loads all profiles into Data.profiles
// returns the profile with the given UUID
- public static MobileLedgerProfile loadAllFromDB(String currentProfileUUID) {
+ public static MobileLedgerProfile loadAllFromDB(@Nullable String currentProfileUUID) {
MobileLedgerProfile result = null;
ArrayList<MobileLedgerProfile> list = new ArrayList<>();
SQLiteDatabase db = App.getDatabase();
db.endTransaction();
}
}
+ public LiveData<ArrayList<LedgerAccount>> getAccounts() {
+ return accounts;
+ }
+ synchronized public void scheduleAccountListReload() {
+ Logger.debug("async-acc", "scheduleAccountListReload() enter");
+ if ((loader != null) && loader.isAlive()) {
+ Logger.debug("async-acc", "returning early - loader already active");
+ return;
+ }
+
+ Logger.debug("async-acc", "Starting AccountListLoader");
+ loader = new AccountListLoader(this);
+ loader.start();
+ }
+ synchronized public void abortAccountListReload() {
+ if (loader == null)
+ return;
+ loader.interrupt();
+ loader = null;
+ }
public boolean getShowCommentsByDefault() {
return showCommentsByDefault;
}
public void storeAccount(SQLiteDatabase db, LedgerAccount acc) {
// replace into is a bad idea because it would reset hidden to its default value
// we like the default, but for new accounts only
- db.execSQL("update accounts set level = ?, keep = 1, hidden=?, expanded=? " +
+ db.execSQL("update accounts set level = ?, keep = 1, expanded=? " +
"where profile=? and name = ?",
- new Object[]{acc.getLevel(), acc.isHiddenByStar(), acc.isExpanded(), uuid,
- acc.getName()
+ new Object[]{acc.getLevel(), acc.isExpanded(), uuid, acc.getName()
});
- db.execSQL("insert into accounts(profile, name, name_upper, parent_name, level, hidden, " +
- "expanded, keep) " + "select ?,?,?,?,?,?,?,1 where (select changes() = 0)",
+ db.execSQL("insert into accounts(profile, name, name_upper, parent_name, level, " +
+ "expanded, keep) " + "select ?,?,?,?,?,?,1 where (select changes() = 0)",
new Object[]{uuid, acc.getName(), acc.getName().toUpperCase(), acc.getParentName(),
- acc.getLevel(), acc.isHiddenByStar(), acc.isExpanded()
+ acc.getLevel(), acc.isExpanded()
});
// debug("accounts", String.format("Stored account '%s' in DB [%s]", acc.getName(), uuid));
}
db.execSQL("DELETE from transaction_accounts WHERE profile = ? and transaction_id=?",
new Object[]{uuid, tr.getId()});
- db.execSQL(
- "INSERT INTO transactions(profile, id, year, month, day, description, "+
- "comment, data_hash, keep) " +
- "values(?,?,?,?,?,?,?,?,1)",
+ db.execSQL("INSERT INTO transactions(profile, id, year, month, day, description, " +
+ "comment, data_hash, keep) values(?,?,?,?,?,?,?,?,1)",
new Object[]{uuid, tr.getId(), tr.getDate().year, tr.getDate().month,
- tr.getDate().day, tr.getDescription(),
- tr.getComment(), tr.getDataHash()
+ tr.getDate().day, tr.getDescription(), tr.getComment(),
+ tr.getDataHash()
});
for (LedgerTransactionAccount item : tr.getAccounts()) {
}
@Nullable
public LedgerAccount tryLoadAccount(SQLiteDatabase db, String accName) {
- try (Cursor cursor = db.rawQuery(
- "SELECT a.hidden, a.expanded, (select 1 from accounts a2 " +
- "where a2.profile = a.profile and a2.name like a.name||':%' limit 1) " +
- "FROM accounts a WHERE a.profile = ? and a.name=?", new String[]{uuid, accName}))
+ try (Cursor cursor = db.rawQuery("SELECT a.expanded, a.amounts_expanded, (select 1 from accounts a2 " +
+ "where a2.profile = a.profile and a2.name like a" +
+ ".name||':%' limit 1) " +
+ "FROM accounts a WHERE a.profile = ? and a.name=?",
+ new String[]{uuid, accName}))
{
if (cursor.moveToFirst()) {
- LedgerAccount acc = new LedgerAccount(accName);
- acc.setHiddenByStar(cursor.getInt(0) == 1);
- acc.setExpanded(cursor.getInt(1) == 1);
+ LedgerAccount acc = new LedgerAccount(this, accName);
+ acc.setExpanded(cursor.getInt(0) == 1);
+ acc.setAmountsExpanded(cursor.getInt(1) == 1);
acc.setHasSubAccounts(cursor.getInt(2) == 1);
try (Cursor c2 = db.rawQuery(
db.execSQL("delete from transactions where profile=?", pUuid);
db.execSQL("delete from transaction_accounts where profile=?", pUuid);
db.setTransactionSuccessful();
- Logger.debug("wipe", String.format(Locale.ENGLISH, "Profile %s wiped out", pUuid[0]));
+ debug("wipe", String.format(Locale.ENGLISH, "Profile %s wiped out", pUuid[0]));
}
finally {
db.endTransaction();
return null;
}
}
+ public Calendar getFirstTransactionDate() {
+ return firstTransactionDate;
+ }
+ public Calendar getLastTransactionDate() {
+ return lastTransactionDate;
+ }
+ public void setAccounts(ArrayList<LedgerAccount> list) {
+ accounts.postValue(list);
+ }
public enum FutureDates {
None(0), OneWeek(7), TwoWeeks(14), OneMonth(30), TwoMonths(60), ThreeMonths(90),
SixMonths(180), OneYear(365), All(-1);
}
}
}
+
+ static class AccountListLoader extends Thread {
+ MobileLedgerProfile profile;
+ AccountListLoader(MobileLedgerProfile profile) {
+ this.profile = profile;
+ }
+ @Override
+ public void run() {
+ Logger.debug("async-acc", "AccountListLoader::run() entered");
+ String profileUUID = profile.getUuid();
+ ArrayList<LedgerAccount> newList = new ArrayList<>();
+
+ String sql = "SELECT a.name from accounts a WHERE a.profile = ?";
+ sql += " ORDER BY a.name";
+
+ SQLiteDatabase db = App.getDatabase();
+ try (Cursor cursor = db.rawQuery(sql, new String[]{profileUUID})) {
+ while (cursor.moveToNext()) {
+ if (isInterrupted())
+ return;
+
+ final String accName = cursor.getString(0);
+// debug("accounts",
+// String.format("Read account '%s' from DB [%s]", accName,
+// profileUUID));
+ LedgerAccount acc = profile.loadAccount(db, accName);
+ if (acc.isVisible(newList))
+ newList.add(acc);
+ }
+ }
+
+ if (isInterrupted())
+ return;
+
+ Logger.debug("async-acc", "AccountListLoader::run() posting new list");
+ profile.accounts.postValue(newList);
+ }
+ }
}