Skip to content

Commit

Permalink
Merge branch 'develop' into release/v2.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
codinguser committed Aug 16, 2016
2 parents cee5600 + 86ac841 commit 7b345af
Show file tree
Hide file tree
Showing 29 changed files with 884 additions and 379 deletions.
2 changes: 1 addition & 1 deletion app/build.gradle
Expand Up @@ -7,7 +7,7 @@ apply plugin: 'io.fabric'
def versionMajor = 2
def versionMinor = 1
def versionPatch = 0
def versionBuild = 2
def versionBuild = 3

def buildTime() {
def df = new SimpleDateFormat("yyyyMMdd HH:mm 'UTC'")
Expand Down
Expand Up @@ -71,6 +71,17 @@ public void shouldOpenBookManager(){
Intents.intended(hasComponent(PreferenceActivity.class.getName()));
}

public void testLoadBookFromBookManager(){
Book book = new Book();
book.setDisplayName("Launch Codes");
BooksDbAdapter.getInstance().addRecord(book);

shouldOpenBookManager();
onView(withText(book.getDisplayName())).perform(click());

assertThat(BooksDbAdapter.getInstance().getActiveBookUID()).isEqualTo(book.getUID());
}

@Test
public void creatingNewAccounts_shouldCreatedNewBook(){
long booksCount = mBooksDbAdapter.getRecordsCount();
Expand Down
Expand Up @@ -561,8 +561,7 @@ public void testDeleteTransaction(){
onView(withId(R.id.options_menu)).perform(click());
onView(withText(R.string.menu_delete)).perform(click());

long id = mAccountsDbAdapter.getID(TRANSACTIONS_ACCOUNT_UID);
assertThat(0).isEqualTo(mTransactionsDbAdapter.getTransactionsCount(id));
assertThat(0).isEqualTo(mTransactionsDbAdapter.getTransactionsCount(TRANSACTIONS_ACCOUNT_UID));
}

@Test
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/AndroidManifest.xml
Expand Up @@ -125,7 +125,7 @@
android:enabled="true"
android:exported="false"
android:label="Dropbox Sync" />
<service android:name=".service.SchedulerService"
<service android:name=".service.ScheduledActionService"
android:exported="false"
android:label="GnuCash Android Scheduler Execution Service"/>
<receiver android:name=".receivers.TransactionRecorder"
Expand Down
36 changes: 25 additions & 11 deletions app/src/main/java/org/gnucash/android/app/GnuCashApplication.java
Expand Up @@ -25,6 +25,7 @@
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.os.Build;
import android.os.SystemClock;
import android.support.annotation.NonNull;
import android.support.v7.preference.PreferenceManager;
import android.util.Log;
Expand All @@ -51,7 +52,7 @@
import org.gnucash.android.db.adapter.TransactionsDbAdapter;
import org.gnucash.android.model.Commodity;
import org.gnucash.android.model.Money;
import org.gnucash.android.service.SchedulerService;
import org.gnucash.android.service.ScheduledActionService;
import org.gnucash.android.ui.account.AccountsActivity;
import org.gnucash.android.ui.settings.PreferenceActivity;

Expand Down Expand Up @@ -126,12 +127,9 @@ public void onCreate(){
mBooksDbAdapter = new BooksDbAdapter(bookDbHelper.getWritableDatabase());

initDatabaseAdapters();

//TODO: migrate preferences from defaultShared to book

setDefaultCurrencyCode(getDefaultCurrencyCode());

if (BuildConfig.DEBUG)
if (BuildConfig.DEBUG && !isRoboUnitTest())
setUpRemoteDebuggingFromChrome();
}

Expand Down Expand Up @@ -216,6 +214,14 @@ public static void loadBook(@NonNull String bookUID){
AccountsActivity.start(getAppContext());
}

/**
* Returns the currently active database in the application
* @return Currently active {@link SQLiteDatabase}
*/
public static SQLiteDatabase getActiveDb(){
return mDbHelper.getWritableDatabase();
}

/**
* Returns the application context
* @return Application {@link Context} object
Expand All @@ -232,6 +238,14 @@ public static boolean isCrashlyticsEnabled(){
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(context.getString(R.string.key_enable_crashlytics), false);
}

/**
* Returns {@code true} if the app is being run by robolectric
* @return {@code true} if in unit testing, {@code false} otherwise
*/
public static boolean isRoboUnitTest(){
return "robolectric".equals(Build.FINGERPRINT);
}

/**
* Returns <code>true</code> if double entry is enabled in the app settings, <code>false</code> otherwise.
* If the value is not set, the default value can be specified in the parameters.
Expand Down Expand Up @@ -327,18 +341,18 @@ public static Locale getDefaultLocale() {
* @param context Application context
*/
public static void startScheduledActionExecutionService(Context context){
Intent alarmIntent = new Intent(context, SchedulerService.class);
Intent alarmIntent = new Intent(context, ScheduledActionService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null)

if (pendingIntent != null) //if service is already scheduled, just return
return;
else
pendingIntent = PendingIntent.getService(context, 0, alarmIntent, 0);

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,
System.currentTimeMillis() + AlarmManager.INTERVAL_DAY,
AlarmManager.INTERVAL_HALF_DAY,
pendingIntent);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_FIFTEEN_MINUTES,
AlarmManager.INTERVAL_HALF_DAY, pendingIntent);

context.startService(alarmIntent); //run the service the first time
}
Expand Down
10 changes: 10 additions & 0 deletions app/src/main/java/org/gnucash/android/db/MigrationHelper.java
Expand Up @@ -46,6 +46,7 @@
import org.gnucash.android.model.Recurrence;
import org.gnucash.android.model.ScheduledAction;
import org.gnucash.android.model.Transaction;
import org.gnucash.android.service.ScheduledActionService;
import org.gnucash.android.util.PreferencesHelper;
import org.gnucash.android.util.TimestampHelper;
import org.xml.sax.InputSource;
Expand Down Expand Up @@ -1463,6 +1464,15 @@ static int upgradeDbToVersion13(SQLiteDatabase db){
.putBoolean(keyUseCompactView, useCompactTrnView)
.apply();

//cancel the existing pending intent so that the alarm can be rescheduled
Intent alarmIntent = new Intent(context, ScheduledActionService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
pendingIntent.cancel();

GnuCashApplication.startScheduledActionExecutionService(GnuCashApplication.getAppContext());

return oldVersion;
}
}
Expand Up @@ -77,6 +77,11 @@ public class AccountsDbAdapter extends DatabaseAdapter<Account> {
*/
private final TransactionsDbAdapter mTransactionsAdapter;

/**
* Commodities database adapter for commodity manipulation
*/
private final CommoditiesDbAdapter mCommoditiesDbAdapter;

/**
* Overloaded constructor. Creates an adapter for an already open database
* @param db SQliteDatabase instance
Expand All @@ -98,6 +103,35 @@ public AccountsDbAdapter(SQLiteDatabase db, TransactionsDbAdapter transactionsDb
AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID
});
mTransactionsAdapter = transactionsDbAdapter;
mCommoditiesDbAdapter = new CommoditiesDbAdapter(db);
}

/**
* Convenience overloaded constructor.
* This is used when an AccountsDbAdapter object is needed quickly. Otherwise, the other
* constructor {@link #AccountsDbAdapter(SQLiteDatabase, TransactionsDbAdapter)}
* should be used whenever possible
* @param db Database to create an adapter for
*/
public AccountsDbAdapter(SQLiteDatabase db){
super(db, AccountEntry.TABLE_NAME, new String[]{
AccountEntry.COLUMN_NAME ,
AccountEntry.COLUMN_DESCRIPTION ,
AccountEntry.COLUMN_TYPE ,
AccountEntry.COLUMN_CURRENCY ,
AccountEntry.COLUMN_COLOR_CODE ,
AccountEntry.COLUMN_FAVORITE ,
AccountEntry.COLUMN_FULL_NAME ,
AccountEntry.COLUMN_PLACEHOLDER ,
AccountEntry.COLUMN_CREATED_AT ,
AccountEntry.COLUMN_HIDDEN ,
AccountEntry.COLUMN_COMMODITY_UID,
AccountEntry.COLUMN_PARENT_ACCOUNT_UID,
AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID
});

mTransactionsAdapter = new TransactionsDbAdapter(db, new SplitsDbAdapter(db));
mCommoditiesDbAdapter = new CommoditiesDbAdapter(db);
}

/**
Expand Down Expand Up @@ -407,7 +441,7 @@ private Account buildSimpleAccountInstance(Cursor c) {
account.setParentUID(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_PARENT_ACCOUNT_UID)));
account.setAccountType(AccountType.valueOf(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_TYPE))));
Currency currency = Currency.getInstance(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_CURRENCY)));
account.setCommodity(CommoditiesDbAdapter.getInstance().getCommodity(currency.getCurrencyCode()));
account.setCommodity(mCommoditiesDbAdapter.getCommodity(currency.getCurrencyCode()));
account.setPlaceHolderFlag(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_PLACEHOLDER)) == 1);
account.setDefaultTransferAccountUID(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID)));
String color = c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_COLOR_CODE));
Expand Down Expand Up @@ -552,7 +586,7 @@ public List<Account> getExportableAccounts(Timestamp lastExportTimeStamp){
*/
public String getOrCreateImbalanceAccountUID(Currency currency){
String imbalanceAccountName = getImbalanceAccountName(currency);
Commodity commodity = CommoditiesDbAdapter.getInstance().getCommodity(currency.getCurrencyCode());
Commodity commodity = mCommoditiesDbAdapter.getCommodity(currency.getCurrencyCode());
String uid = findAccountUidByFullName(imbalanceAccountName);
if (uid == null){
Account account = new Account(imbalanceAccountName, commodity);
Expand Down Expand Up @@ -755,7 +789,7 @@ public Money getAccountBalance(AccountType accountType, long startTimestamp, lon
String currencyCode = GnuCashApplication.getDefaultCurrencyCode();

Log.d(LOG_TAG, "all account list : " + accountUidList.size());
SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance();
SplitsDbAdapter splitsDbAdapter = mTransactionsAdapter.getSplitDbAdapter();

return (startTimestamp == -1 && endTimestamp == -1)
? splitsDbAdapter.computeSplitBalance(accountUidList, currencyCode, hasDebitNormalBalance)
Expand Down Expand Up @@ -788,7 +822,7 @@ private Money computeBalance(String accountUID, long startTimestamp, long endTim
accountsList.add(0, accountUID);

Log.d(LOG_TAG, "all account list : " + accountsList.size());
SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance();
SplitsDbAdapter splitsDbAdapter = mTransactionsAdapter.getSplitDbAdapter();
return (startTimestamp == -1 && endTimestamp == -1)
? splitsDbAdapter.computeSplitBalance(accountsList, currencyCode, hasDebitNormalBalance)
: splitsDbAdapter.computeSplitBalance(accountsList, currencyCode, hasDebitNormalBalance, startTimestamp, endTimestamp);
Expand All @@ -812,7 +846,7 @@ public Money getAccountsBalance(@NonNull List<String> accountUIDList, long star

boolean hasDebitNormalBalance = getAccountType(accountUIDList.get(0)).hasDebitNormalBalance();

SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance();
SplitsDbAdapter splitsDbAdapter = mTransactionsAdapter.getSplitDbAdapter();
Money splitSum = (startTimestamp == -1 && endTimestamp == -1)
? splitsDbAdapter.computeSplitBalance(accountUIDList, currencyCode, hasDebitNormalBalance)
: splitsDbAdapter.computeSplitBalance(accountUIDList, currencyCode, hasDebitNormalBalance, startTimestamp, endTimestamp);
Expand Down
Expand Up @@ -100,7 +100,7 @@ public Book buildModelInstance(@NonNull Cursor cursor) {
*/
public String setActive(@NonNull String bookUID){
if (bookUID == null)
return BooksDbAdapter.getInstance().getActiveBookUID();
return getActiveBookUID();

ContentValues contentValues = new ContentValues();
contentValues.put(BookEntry.COLUMN_ACTIVE, 0);
Expand Down
Expand Up @@ -186,6 +186,6 @@ public Money getAccountSum(String budgetUID, long periodStart, long periodEnd){
accountUIDs.add(budgetAmount.getAccountUID());
}

return AccountsDbAdapter.getInstance().getAccountsBalance(accountUIDs, periodStart, periodEnd);
return new AccountsDbAdapter(mDb).getAccountsBalance(accountUIDs, periodStart, periodEnd);
}
}
Expand Up @@ -721,7 +721,24 @@ public boolean deleteRecord(@NonNull String uid){
* @throws IllegalArgumentException if either the {@code recordUID} or {@code columnName} do not exist in the database
*/
public String getAttribute(@NonNull String recordUID, @NonNull String columnName){
Cursor cursor = mDb.query(mTableName,
return getAttribute(mTableName, recordUID, columnName);
}

/**
* Returns an attribute from a specific column in the database for a specific record and specific table.
* <p>The attribute is returned as a string which can then be converted to another type if
* the caller was expecting something other type </p>
* <p>This method is an override of {@link #getAttribute(String, String)} which allows to select a value from a
* different table than the one of current adapter instance
* </p>
* @param tableName Database table name. See {@link DatabaseSchema}
* @param recordUID GUID of the record
* @param columnName Name of the column to be retrieved
* @return String value of the column entry
* @throws IllegalArgumentException if either the {@code recordUID} or {@code columnName} do not exist in the database
*/
protected String getAttribute(@NonNull String tableName, @NonNull String recordUID, @NonNull String columnName){
Cursor cursor = mDb.query(tableName,
new String[]{columnName},
AccountEntry.COLUMN_UID + " = ?",
new String[]{recordUID}, null, null, null);
Expand Down
Expand Up @@ -104,7 +104,7 @@ public long bulkAddRecords(@NonNull List<ScheduledAction> scheduledActions, Upda
public long updateRecurrenceAttributes(ScheduledAction scheduledAction){
//since we are updating, first fetch the existing recurrence UID and set it to the object
//so that it will be updated and not a new one created
RecurrenceDbAdapter recurrenceDbAdapter = RecurrenceDbAdapter.getInstance();
RecurrenceDbAdapter recurrenceDbAdapter = new RecurrenceDbAdapter(mDb);
String recurrenceUID = recurrenceDbAdapter.getAttribute(scheduledAction.getUID(), ScheduledActionEntry.COLUMN_RECURRENCE_UID);

Recurrence recurrence = scheduledAction.getRecurrence();
Expand All @@ -116,7 +116,7 @@ public long updateRecurrenceAttributes(ScheduledAction scheduledAction){
contentValues.put(ScheduledActionEntry.COLUMN_START_TIME, scheduledAction.getStartTime());
contentValues.put(ScheduledActionEntry.COLUMN_END_TIME, scheduledAction.getEndTime());
contentValues.put(ScheduledActionEntry.COLUMN_TAG, scheduledAction.getTag());
contentValues.put(ScheduledActionEntry.COLUMN_TOTAL_FREQUENCY, scheduledAction.getTotalFrequency());
contentValues.put(ScheduledActionEntry.COLUMN_TOTAL_FREQUENCY, scheduledAction.getTotalPlannedExecutionCount());

Log.d(LOG_TAG, "Updating scheduled event recurrence attributes");
String where = ScheduledActionEntry.COLUMN_UID + "=?";
Expand All @@ -138,7 +138,7 @@ public long updateRecurrenceAttributes(ScheduledAction scheduledAction){
stmt.bindNull(8);
else
stmt.bindString(8, schedxAction.getTag());
stmt.bindString(9, Integer.toString(schedxAction.getTotalFrequency()));
stmt.bindString(9, Integer.toString(schedxAction.getTotalPlannedExecutionCount()));
stmt.bindString(10, schedxAction.getRecurrence().getUID());
stmt.bindLong(11, schedxAction.shouldAutoCreate() ? 1 : 0);
stmt.bindLong(12, schedxAction.shouldAutoNotify() ? 1 : 0);
Expand Down Expand Up @@ -182,7 +182,7 @@ public ScheduledAction buildModelInstance(@NonNull final Cursor cursor){
event.setLastRun(lastRun);
event.setTag(tag);
event.setEnabled(enabled);
event.setTotalFrequency(numOccurrences);
event.setTotalPlannedExecutionCount(numOccurrences);
event.setExecutionCount(execCount);
event.setAutoCreate(autoCreate == 1);
event.setAutoNotify(autoNotify == 1);
Expand Down
Expand Up @@ -131,7 +131,7 @@ public Split buildModelInstance(@NonNull final Cursor cursor){
String reconcileState = cursor.getString(cursor.getColumnIndexOrThrow(SplitEntry.COLUMN_RECONCILE_STATE));
String reconcileDate = cursor.getString(cursor.getColumnIndexOrThrow(SplitEntry.COLUMN_RECONCILE_DATE));

String transactionCurrency = TransactionsDbAdapter.getInstance().getAttribute(transxUID, TransactionEntry.COLUMN_CURRENCY);
String transactionCurrency = getAttribute(TransactionEntry.TABLE_NAME, transxUID, TransactionEntry.COLUMN_CURRENCY);
Money value = new Money(valueNum, valueDenom, transactionCurrency);
String currencyCode = getAccountCurrencyCode(accountUID);
Money quantity = new Money(quantityNum, quantityDenom, currencyCode);
Expand Down

0 comments on commit 7b345af

Please sign in to comment.