Skip to content

Commit

Permalink
Merge branch 'release/v2.4.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
codinguser committed Jun 15, 2018
2 parents 13304f0 + 78fa394 commit 879596c
Show file tree
Hide file tree
Showing 62 changed files with 1,880 additions and 452 deletions.
9 changes: 6 additions & 3 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,25 @@ android:
- platform-tools
- tools
- tools #not a typo. Needed for SDK update
- build-tools-27.0.0
- build-tools-27.0.3

# The SDK version used to compile your project
- android-26
- android-27

# Additional components
- extra-android-support
- extra-google-google_play_services
- extra-google-m2repository
- extra-android-m2repository
- addon-google_apis-google-25
- addon-google_apis-google-26

# Specify at least one system image,
# if you need to run emulator(s) during your tests
#- sys-img-armeabi-v7a-android-23

# XXX: Temporary workaround. Remove once fixed
before_install:
- yes | sdkmanager "platforms;android-27"

# Emulator Management: Create, Start and Wait
# Re-enable this when we figure out how to reliably build on Travis
Expand Down
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
Change Log
===============================================================================
Version 2.4.0 *(2018-06-15)*
----------------------------
* Feature #665: Adds CSV export format
* Feature #544: Add extra checkbox confirmation for irreversible actions
* Feature #767: Backup before destructive actions
* Feature #465: Account balances now include future transactions
* Fixed #764: Crash when importing XML files from Gnucash desktop v2.7 and up
* Fixed #768: ScheduledActionService crashes on Android 8 (Oreo)
* Fixed #731: Double display of Persian currency symbol
* Fixed #771: QIF export crashes due to illegal denominator
* Fixed #757: Backups are created every hour
* Fixed #766: Backups are kept forever


Version 2.3.0 *(2018-01-10)*
----------------------------
* Feature #544: Use double confirmation dialog boxes before irreversible actions
Expand Down
3 changes: 3 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The following people (in alphabetical order) contributed (commits on GitHub) to
* Falk Brockmann
* Felipe Morato
* Geert Janssens
* Gleb Semyannikov
* Jörg Möller
* Israel Buitron
* Jesse Shieh
Expand Down Expand Up @@ -54,6 +55,8 @@ The following people (in alphabetical order) contributed (commits on GitHub) to
* Stephan Windmüller
* Terry Chung
* thesebas thesebas@thesebas.net
* Timur Badretdinov
* Timur Khuzin
* Vladimir Rutsky
* Weslly Oliveira
* windwarrior lennartbuit@gmail.com
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Accounts | Transactions | Reports
:-------------------------:|:-------------------------:|:-------------------------:
![Accounts List](docs/images/v2.0.0_home.png) | ![Transactions List](docs/images/v2.0.0_transactions_list.png) | ![Reports](docs/images/v2.0.0_reports.png)

The application supports Android 4.4 KitKat (API level 19) and above.
The application supports Android 4.4 KitKat (API level 19) and above.

Features include:

Expand Down Expand Up @@ -90,9 +90,10 @@ There are several ways you could contribute to the development.

* Pull requests are always welcome! You could contribute code by fixing bugs, adding new features or automated tests.
Take a look at the [bug tracker](https://github.com/codinguser/gnucash-android/issues?state=open)
for ideas where to start. Also make sure to read our [contribution guidlines](https://github.com/codinguser/gnucash-android/blob/master/.github/CONTRIBUTING.md)
for ideas where to start. It is also preferable to target issues in the current [milestone](https://github.com/codinguser/gnucash-android/milestones).
* Make sure to read our [contribution guidelines](https://github.com/codinguser/gnucash-android/blob/master/.github/CONTRIBUTING.md) before starting to code.

* One way is providing translations for locales which are not yet available, or improving translations.
* Another way to contribute is by providing translations for languages, or improving translations.
Please visit [CrowdIn](https://crowdin.com/project/gnucash-android) in order to update and create new translations

For development, it is recommended to use the Android Studio for development which is available for free.
Expand Down
87 changes: 44 additions & 43 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ apply plugin: 'com.android.application'
apply plugin: 'io.fabric'

def versionMajor = 2
def versionMinor = 3
def versionMinor = 4
def versionPatch = 0
def versionBuild = 4
def versionBuild = 3

static def buildTime() {
def df = new SimpleDateFormat("yyyyMMdd HH:mm 'UTC'")
Expand All @@ -20,13 +20,13 @@ static def gitSha() {


android {
compileSdkVersion 26
buildToolsVersion '27.0.0'
compileSdkVersion 27
buildToolsVersion '27.0.3'
defaultConfig {
applicationId "org.gnucash.android"
testApplicationId 'org.gnucash.android.test'
minSdkVersion 19
targetSdkVersion 26
targetSdkVersion 27
versionCode versionMajor * 10000 + versionMinor * 1000 + versionPatch * 100 + versionBuild
versionName "${versionMajor}.${versionMinor}.${versionPatch}"
resValue "string", "app_version_name", "${versionName}"
Expand Down Expand Up @@ -179,7 +179,7 @@ afterEvaluate {
}


def androidSupportVersion = "26.0.1"
def androidSupportVersion = "27.0.2"
def androidEspressoVersion = "3.0.0"
def androidSupportTestVersion = "1.0.0"

Expand All @@ -190,69 +190,70 @@ repositories{
}

dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.github.nextcloud:android-library:1.0.31'
compile('com.android.support:support-v4:' + androidSupportVersion,
'com.android.support:appcompat-v7:' + androidSupportVersion,
'com.android.support:design:' + androidSupportVersion,
'com.android.support:cardview-v7:' + androidSupportVersion,
'com.android.support:preference-v7:' + androidSupportVersion,
'com.android.support:recyclerview-v7:' + androidSupportVersion,
'com.code-troopers.betterpickers:library:3.1.0',
'org.jraf:android-switch-backport:2.0.1@aar',
'com.github.PhilJay:MPAndroidChart:v2.1.3',
'joda-time:joda-time:2.9.4',
'com.google.android.gms:play-services-drive:9.6.1',
'io.github.kobakei:ratethisapp:1.1.3',
'com.squareup:android-times-square:1.6.5@aar',
'com.github.techfreak:wizardpager:1.0.3',
'net.objecthunter:exp4j:0.4.7',
'org.apache.jackrabbit:jackrabbit-webdav:2.13.3',
'com.dropbox.core:dropbox-core-sdk:3.0.3',
'com.android.support:multidex:1.0.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.github.nextcloud:android-library:1.0.31'
implementation('com.android.support:support-v4:' + androidSupportVersion,
'com.android.support:appcompat-v7:' + androidSupportVersion,
'com.android.support:design:' + androidSupportVersion,
'com.android.support:cardview-v7:' + androidSupportVersion,
'com.android.support:preference-v7:' + androidSupportVersion,
'com.android.support:recyclerview-v7:' + androidSupportVersion,
'com.code-troopers.betterpickers:library:3.1.0',
'org.jraf:android-switch-backport:2.0.1@aar',
'com.github.PhilJay:MPAndroidChart:v2.1.3',
'joda-time:joda-time:2.9.4',
'com.google.android.gms:play-services-drive:9.6.1',
'io.github.kobakei:ratethisapp:1.1.3',
'com.squareup:android-times-square:1.6.5@aar',
'com.github.techfreak:wizardpager:1.0.3',
'net.objecthunter:exp4j:0.4.7',
'org.apache.jackrabbit:jackrabbit-webdav:2.13.3',
'com.dropbox.core:dropbox-core-sdk:3.0.3',
'com.android.support:multidex:1.0.1'
)

debugCompile 'com.facebook.stetho:stetho:1.5.0'
debugImplementation 'com.facebook.stetho:stetho:1.5.0'

compile 'com.jakewharton:butterknife:8.8.1'
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'

compile ('com.uservoice:uservoice-android-sdk:1.2.6') {
implementation ('com.uservoice:uservoice-android-sdk:1.2.6') {
exclude module: 'commons-logging'
exclude module: 'httpcore'
exclude module: 'httpclient'
}

compile('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {
implementation('com.crashlytics.sdk.android:crashlytics:2.6.7@aar') {
transitive = true;
}


testImplementation 'org.robolectric:robolectric:3.5.1'

testCompile(
testImplementation(
'junit:junit:4.12',
'joda-time:joda-time:2.9.4',
'org.assertj:assertj-core:1.7.1'
)
testCompile 'org.robolectric:shadows-multidex:3.0'

androidTestCompile ('com.android.support:support-annotations:' + androidSupportVersion,
'com.android.support.test:runner:' + androidSupportTestVersion,
'com.android.support.test:rules:' + androidSupportTestVersion,
'com.android.support.test.espresso:espresso-core:' + androidEspressoVersion,
'com.android.support.test.espresso:espresso-intents:' + androidEspressoVersion,
testImplementation 'org.robolectric:shadows-multidex:3.0'

androidTestImplementation (
'com.android.support:support-annotations:' + androidSupportVersion,
'com.android.support.test:runner:' + androidSupportTestVersion,
'com.android.support.test:rules:' + androidSupportTestVersion,
'com.android.support.test.espresso:espresso-core:' + androidEspressoVersion,
'com.android.support.test.espresso:espresso-intents:' + androidEspressoVersion,
//the following are only added so that the app and test version both us the same versions
'com.android.support:appcompat-v7:' + androidSupportVersion,
'com.android.support:design:' + androidSupportVersion)
androidTestCompile ('com.android.support.test.espresso:espresso-contrib:' + androidEspressoVersion) {
'com.android.support:appcompat-v7:' + androidSupportVersion,
'com.android.support:design:' + androidSupportVersion)
androidTestImplementation ('com.android.support.test.espresso:espresso-contrib:' + androidEspressoVersion) {
exclude group: 'com.android.support', module: 'support-v4'
exclude module: 'recyclerview-v7'
}

androidTestCompile('com.squareup.assertj:assertj-android:1.1.1'){
androidTestImplementation('com.squareup.assertj:assertj-android:1.1.1'){
exclude group: 'com.android.support', module:'support-annotations'
}

androidTestCompile 'com.squareup.spoon:spoon-client:1.6.4'
androidTestImplementation 'com.squareup.spoon:spoon-client:1.6.4'
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,11 @@
package org.gnucash.android.test.ui;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences.Editor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.Build;
import android.preference.PreferenceManager;
import android.support.test.espresso.Espresso;
import android.support.test.espresso.matcher.ViewMatchers;
Expand All @@ -32,6 +30,7 @@
import android.support.test.runner.AndroidJUnit4;
import android.support.v4.app.Fragment;
import android.util.Log;
import android.view.View;

import com.kobakei.ratethisapp.RateThisApp;

Expand All @@ -54,6 +53,9 @@
import org.gnucash.android.test.ui.util.DisableAnimationsRule;
import org.gnucash.android.ui.account.AccountsActivity;
import org.gnucash.android.ui.account.AccountsListFragment;
import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
Expand Down Expand Up @@ -87,6 +89,7 @@
import static android.support.test.espresso.matcher.ViewMatchers.withText;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.not;
Expand Down Expand Up @@ -236,6 +239,21 @@ public void testCreateAccount(){
assertThat(newestAccount.isPlaceholderAccount()).isTrue();
}

@Test
public void should_IncludeFutureTransactionsInAccountBalance(){
Transaction transaction = new Transaction("Future transaction");
Split split1 = new Split(new Money("4.15", ACCOUNTS_CURRENCY_CODE), SIMPLE_ACCOUNT_UID);
transaction.addSplit(split1);
transaction.setTime(System.currentTimeMillis() + 4815162342L);
mTransactionsDbAdapter.addRecord(transaction);

refreshAccountsList();

List<Transaction> trxns = mTransactionsDbAdapter.getAllTransactions();

onView(first(withText(containsString("4.15")))).check(matches(isDisplayed()));
}

@Test
public void testChangeParentAccount() {
final String accountName = "Euro Account";
Expand Down Expand Up @@ -511,4 +529,31 @@ public void run() {
System.err.println("Failed to refresh fragment");
}
}

/**
* Matcher to select the first of multiple views which are matched in the UI
* @param expected Matcher which fits multiple views
* @return Single match
*/
public static Matcher<View> first(final Matcher<View> expected){

return new TypeSafeMatcher<View>() {
private boolean first = false;

@Override
protected boolean matchesSafely(View item) {

if( expected.matches(item) && !first ){
return first = true;
}

return false;
}

@Override
public void describeTo(Description description) {
description.appendText("Matcher.first( " + expected.toString() + " )" );
}
};
}
}
10 changes: 10 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,10 @@
</activity>
<service android:name=".service.ScheduledActionService"
android:exported="false"
android:permission="android.permission.BIND_JOB_SERVICE"
android:label="GnuCash Android Scheduler Execution Service"/>
<service android:name=".util.BackupJob"
android:permission="android.permission.BIND_JOB_SERVICE" />
<receiver android:name=".receivers.TransactionRecorder"
android:label="Records transactions received through intents"
android:permission="org.gnucash.android.permission.RECORD_TRANSACTION">
Expand Down Expand Up @@ -154,6 +157,13 @@
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
<receiver
android:name=".receivers.PeriodicJobReceiver" android:exported="false">
<intent-filter>
<action android:name="org.gnucash.android.action_backup" />
<action android:name="org.gnucash.android.action_scheduled_actions" />
</intent-filter>
</receiver>
<provider
android:authorities="${applicationId}.fileprovider"
android:name="android.support.v4.content.FileProvider"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@
import org.gnucash.android.db.adapter.ScheduledActionDbAdapter;
import org.gnucash.android.db.adapter.SplitsDbAdapter;
import org.gnucash.android.db.adapter.TransactionsDbAdapter;
import org.gnucash.android.model.Book;
import org.gnucash.android.model.Commodity;
import org.gnucash.android.model.Money;
import org.gnucash.android.receivers.PeriodicJobReceiver;
import org.gnucash.android.service.ScheduledActionService;
import org.gnucash.android.ui.settings.PreferenceActivity;

Expand Down Expand Up @@ -333,20 +333,22 @@ public static Locale getDefaultLocale() {
* @param context Application context
*/
public static void startScheduledActionExecutionService(Context context){
Intent alarmIntent = new Intent(context, ScheduledActionService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, alarmIntent, PendingIntent.FLAG_NO_CREATE);
Intent alarmIntent = new Intent(context, PeriodicJobReceiver.class);
alarmIntent.setAction(PeriodicJobReceiver.ACTION_SCHEDULED_ACTIONS);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, alarmIntent,
PendingIntent.FLAG_NO_CREATE);

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

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_FIFTEEN_MINUTES,
AlarmManager.INTERVAL_HOUR, pendingIntent);

context.startService(alarmIntent); //run the service the first time
ScheduledActionService.enqueueWork(context);
}

/**
Expand Down
Loading

0 comments on commit 879596c

Please sign in to comment.