diff --git a/.travis.yml b/.travis.yml index a66c86964..1b304c2bd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,20 +1,21 @@ language: android -jdk: oraclejdk7 +jdk: oraclejdk8 android: components: - platform-tools - tools - - build-tools-23.0.3 + - tools #not a typo. Needed for SDK update + - build-tools-24.0.3 # The SDK version used to compile your project - - android-23 + - android-24 # Additional components - extra-android-support - extra-google-google_play_services - extra-google-m2repository - extra-android-m2repository - - addon-google_apis-google-23 + - addon-google_apis-google-24 # Specify at least one system image, # if you need to run emulator(s) during your tests diff --git a/CHANGELOG.md b/CHANGELOG.md index 46f297967..95c4b2c0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ Change Log =============================================================================== +Version 2.1.5 *(2017-04-04)* +---------------------------- +* Fixed: Widget button for placeholder accounts tries to create transactions +* Fixed: App crashes when screen orientation changes while viewing reports (#633) +* Fixed: OFX exporter creates file even when there are no transactions to export +* Fixed: Constant app crashes after creating accounts with BYN currency (#663) +* Fixed: Choosing manual account creation during setup closes wizard but doesn't open accounts view (#644) +* Improved: Upgrade to Dropbox API v2 (v1 will be deprecated soon) (#552) +* Improved: Use FileProvider for sharing files with other applications (#568) +* Improved: Tell user when there are no transactions to export +* Improved: Added option to hide account balance in widget (#600) +* Improved: List transfer accounts starting with favorites first (#622) +* Improved: Management of preferences for widgets and support for multibook widgets +* Improved: Updated translations and added generic default account files for broad locales (e.g. de, fr, pt) + + Version 2.1.4 *(2017-01-30)* ---------------------------- * Fixed: Bugs in execution of some scheduled actions (#604, #609) diff --git a/app/build.gradle b/app/build.gradle index d72adee5b..399b2c261 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,14 +1,13 @@ -import org.apache.tools.ant.taskdefs.condition.Os - import java.text.SimpleDateFormat apply plugin: 'com.android.application' apply plugin: 'io.fabric' +apply plugin: 'android-apt' def versionMajor = 2 def versionMinor = 1 -def versionPatch = 4 -def versionBuild = 2 +def versionPatch = 5 +def versionBuild = 4 def buildTime() { def df = new SimpleDateFormat("yyyyMMdd HH:mm 'UTC'") @@ -22,8 +21,8 @@ def gitSha() { android { - compileSdkVersion 23 - buildToolsVersion '23.0.3' + compileSdkVersion 24 + buildToolsVersion '24.0.3' defaultConfig { applicationId "org.gnucash.android" testApplicationId 'org.gnucash.android.test' @@ -36,15 +35,7 @@ android { buildConfigField "boolean", "CAN_REQUEST_RATING", "false" buildConfigField "String", "BUILD_TIME", "\"${buildTime()}\"" - if (project.hasProperty("RELEASE_DROPBOX_APP_KEY")){ - resValue "string", "dropbox_app_key", RELEASE_DROPBOX_APP_KEY - resValue "string", "dropbox_app_secret", RELEASE_DROPBOX_APP_SECRET - resValue "string", "manifest_dropbox_app_key", "db-${RELEASE_DROPBOX_APP_KEY}" - } else { - resValue "string", "dropbox_app_key", "dhjh8ke9wf05948" - resValue "string", "dropbox_app_secret", "h2t9fphj3nr4wkw" - resValue "string", "manifest_dropbox_app_key", "db-dhjh8ke9wf05948" - } + multiDexEnabled true testInstrumentationRunner "org.gnucash.android.test.ui.util.GnucashAndroidTestRunner" } @@ -109,17 +100,41 @@ android { resValue "string", "app_name", "GnuCash-devel" versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev${versionBuild}_r${gitSha()}" resValue "string", "app_version_name", "${versionName}" + + resValue "string", "dropbox_app_key", "dhjh8ke9wf05948" + resValue "string", "dropbox_app_secret", "h2t9fphj3nr4wkw" + resValue "string", "manifest_dropbox_app_key", "db-dhjh8ke9wf05948" } beta { resValue "string", "app_name", "GnuCash - beta" versionName "${versionMajor}.${versionMinor}.${versionPatch}-beta${versionBuild}" resValue "string", "app_version_name", "${versionName}" + + if (project.hasProperty("RELEASE_DROPBOX_APP_KEY")){ + resValue "string", "dropbox_app_key", RELEASE_DROPBOX_APP_KEY + resValue "string", "dropbox_app_secret", RELEASE_DROPBOX_APP_SECRET + resValue "string", "manifest_dropbox_app_key", "db-${RELEASE_DROPBOX_APP_KEY}" + } else { + resValue "string", "dropbox_app_key", "dhjh8ke9wf05948" + resValue "string", "dropbox_app_secret", "h2t9fphj3nr4wkw" + resValue "string", "manifest_dropbox_app_key", "db-dhjh8ke9wf05948" + } } production { resValue "string", "app_name", "GnuCash" buildConfigField "boolean", "CAN_REQUEST_RATING", "true" + + if (project.hasProperty("RELEASE_DROPBOX_APP_KEY")){ + resValue "string", "dropbox_app_key", RELEASE_DROPBOX_APP_KEY + resValue "string", "dropbox_app_secret", RELEASE_DROPBOX_APP_SECRET + resValue "string", "manifest_dropbox_app_key", "db-${RELEASE_DROPBOX_APP_KEY}" + } else { + resValue "string", "dropbox_app_key", "dhjh8ke9wf05948" + resValue "string", "dropbox_app_secret", "h2t9fphj3nr4wkw" + resValue "string", "manifest_dropbox_app_key", "db-dhjh8ke9wf05948" + } } } @@ -147,46 +162,35 @@ def initCrashlyticsPropertiesIfNeeded() { } } -def adb = Os.isFamily(Os.FAMILY_WINDOWS) ? "..\\scripts\\adb_all.bat" : "../scripts/adb_all.sh" -//def adb = android.getAdbExe().toString() - afterEvaluate { + apply plugin: 'spoon' + spoon { + debug = true + grantAllPermissions = true + } initCrashlyticsPropertiesIfNeeded() +} - task grantTestPermissionsDevel(type: Exec, dependsOn: 'installDevelopmentDebug') { // or install{productFlavour}{buildType} - if (Os.isFamily(Os.FAMILY_WINDOWS)){ - commandLine "cmd", "/c", "$adb", "shell pm grant $android.productFlavors.development.applicationId android.permission.SET_ANIMATION_SCALE" -// commandLine "cmd", "/c", "$adb", "shell pm grant $android.productFlavors.development.applicationId android.permission.WRITE_EXTERNAL_STORAGE" - } else { - commandLine "$adb shell pm grant $android.productFlavors.development.applicationId android.permission.SET_ANIMATION_SCALE".split(' ') -// commandLine "$adb shell pm grant $android.productFlavors.development.applicationId android.permission.WRITE_EXTERNAL_STORAGE".split(' ') - } - } +android.productFlavors.all { flavour -> + def applicationId = flavour.applicationId + def adb = android.getAdbExe().toString() - task grantTestPermissionsProduction(type: Exec, dependsOn: 'installProductionDebug'){ - if (Os.isFamily(Os.FAMILY_WINDOWS)) { - commandLine "cmd", "/c", "$adb", "shell pm grant $android.productFlavors.development.applicationId android.permission.SET_ANIMATION_SCALE" - commandLine "cmd", "/c", "$adb", "shell pm grant $android.productFlavors.development.applicationId android.permission.WRITE_EXTERNAL_STORAGE" - } else { - commandLine "$adb shell pm grant $android.defaultConfig.applicationId android.permission.SET_ANIMATION_SCALE".split(' ') - commandLine "$adb shell pm grant $android.defaultConfig.applicationId android.permission.WRITE_EXTERNAL_STORAGE".split(' ') - } + def grantPermissionsTask = tasks.create("grant${flavour.name.capitalize()}Permissions") << { + "${adb} shell pm grant ${applicationId} android.permission.WRITE_EXTERNAL_STORAGE".execute() + "${adb} shell pm grant ${applicationId} android.permission.SET_ANIMATION_SCALE".execute() } + grantPermissionsTask.description = "Grants permissions for Marshmallow" - // When launching individual tests from Android Studio, it seems that only the assemble tasks - // get called directly, not the install* versions - tasks.each { task -> - if (task.name.startsWith('assembleDevelopmentDebugAndroidTest')){ - task.dependsOn grantTestPermissionsDevel - } else if (task.name.startsWith('assembleBetaDebugAndroidTest')){ - task.dependsOn grantTestPermissionsProduction - } else if (task.name.startsWith('assembleProductionDebugAndroidTest')){ - task.dependsOn grantTestPermissionsProduction + tasks.whenTaskAdded { theTask -> + def assemblePattern = ~"assemble${flavour.name.capitalize()}DebugAndroidTest" + if (assemblePattern.matcher(theTask.name).matches()) { + theTask.dependsOn grantPermissionsTask.name } } } -def androidSupportVersion = "23.3.0" + +def androidSupportVersion = "24.2.1" def androidEspressoVersion = "2.2.2" def androidSupportTestVersion = "0.5" @@ -205,21 +209,25 @@ dependencies { 'com.android.support:cardview-v7:' + androidSupportVersion, 'com.android.support:preference-v7:' + androidSupportVersion, 'com.android.support:recyclerview-v7:' + androidSupportVersion, - 'com.viewpagerindicator:library:2.4.1@aar', - 'com.code-troopers.betterpickers:library:2.5.5', + 'com.code-troopers.betterpickers:library:3.0.1', 'org.jraf:android-switch-backport:2.0.1@aar', 'com.github.PhilJay:MPAndroidChart:v2.1.3', - 'joda-time:joda-time:2.7', - 'com.google.android.gms:play-services-drive:8.3.0', - 'com.jakewharton:butterknife:7.0.1', - 'io.github.kobakei:ratethisapp:1.0.3', + 'joda-time:joda-time:2.9.4', + 'com.google.android.gms:play-services-drive:9.6.1', + 'io.github.kobakei:ratethisapp:1.1.0', 'com.squareup:android-times-square:1.6.5@aar', 'com.github.techfreak:wizardpager:1.0.3', - 'net.objecthunter:exp4j:0.4.5', - 'org.apache.jackrabbit:jackrabbit-webdav:2.11.1' + 'net.objecthunter:exp4j:0.4.7', + 'org.apache.jackrabbit:jackrabbit-webdav:2.13.3', + 'com.dropbox.core:dropbox-core-sdk:2.1.2', + 'com.facebook.stetho:stetho:1.4.1', + 'com.android.support:multidex:1.0.1' ) - compile ('com.uservoice:uservoice-android-sdk:1.2.+') { + compile 'com.jakewharton:butterknife:8.4.0' + apt 'com.jakewharton:butterknife-compiler:8.4.0' + + compile ('com.uservoice:uservoice-android-sdk:1.2.5') { exclude module: 'commons-logging' exclude module: 'httpcore' exclude module: 'httpclient' @@ -229,13 +237,14 @@ dependencies { transitive = true; } - compile 'com.facebook.stetho:stetho:1.3.1' - testCompile('org.robolectric:robolectric:3.1', + testCompile('org.robolectric:robolectric:3.1.2', 'junit:junit:4.12', - 'joda-time:joda-time:2.7', + '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, @@ -252,4 +261,6 @@ dependencies { androidTestCompile('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' } diff --git a/app/libs/dropbox-sync-sdk-android.jar b/app/libs/dropbox-sync-sdk-android.jar deleted file mode 100644 index 518a600f8..000000000 Binary files a/app/libs/dropbox-sync-sdk-android.jar and /dev/null differ diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9e7ef5e63..01f05fcd2 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -12,4 +12,5 @@ } -keep class org.gnucash.android.** {*;} --keep class com.dropbox.** {*;} \ No newline at end of file +-keep class com.dropbox.** {*;} +-keep class android.support.v7.widget.SearchView { *; } \ No newline at end of file diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java index 39b40f2ef..bfa7fb14f 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java @@ -328,7 +328,7 @@ public void editingAccountShouldNotDeleteTransactions(){ Account account = new Account("Transfer Account"); account.setCommodity(Commodity.getInstance(ACCOUNTS_CURRENCY.getCurrencyCode())); Transaction transaction = new Transaction("Simple transaction"); - transaction.setCurrencyCode(ACCOUNTS_CURRENCY.getCurrencyCode()); + transaction.setCommodity(ACCOUNTS_CURRENCY); Split split = new Split(new Money(BigDecimal.TEN, ACCOUNTS_CURRENCY), account.getUID()); transaction.addSplit(split); transaction.addSplit(split.createPair(SIMPLE_ACCOUNT_UID)); diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/ExportTransactionsTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/ExportTransactionsTest.java index c641bce18..cba7a8e40 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/ExportTransactionsTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/ExportTransactionsTest.java @@ -61,7 +61,6 @@ import org.junit.runners.MethodSorters; import java.io.File; -import java.util.Currency; import java.util.List; import static android.support.test.espresso.Espresso.onView; @@ -133,7 +132,8 @@ public void setUp() throws Exception { Split split = new Split(new Money("8.99", currencyCode), account.getUID()); split.setMemo("Hawaii is the best!"); transaction.addSplit(split); - transaction.addSplit(split.createPair(mAccountsDbAdapter.getOrCreateImbalanceAccountUID(Currency.getInstance(currencyCode)))); + transaction.addSplit(split.createPair( + mAccountsDbAdapter.getOrCreateImbalanceAccountUID(Commodity.DEFAULT_COMMODITY))); account.addTransaction(transaction); mAccountsDbAdapter.addRecord(account, DatabaseAdapter.UpdateMethod.insert); diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/OwnCloudExportTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/OwnCloudExportTest.java index c40414e8f..b37d61171 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/OwnCloudExportTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/OwnCloudExportTest.java @@ -49,8 +49,6 @@ import org.junit.runner.RunWith; import org.junit.runners.MethodSorters; -import java.util.Currency; - import static android.support.test.InstrumentationRegistry.getInstrumentation; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.clearText; @@ -132,7 +130,7 @@ public void setUp() throws Exception { Split split = new Split(new Money("11.11", currencyCode), account.getUID()); transaction.addSplit(split); transaction.addSplit(split.createPair( - mAccountsDbAdapter.getOrCreateImbalanceAccountUID(Currency.getInstance(currencyCode)))); + mAccountsDbAdapter.getOrCreateImbalanceAccountUID(Commodity.DEFAULT_COMMODITY))); account.addTransaction(transaction); mAccountsDbAdapter.addRecord(account, DatabaseAdapter.UpdateMethod.insert); diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java index bf5373a56..aa30d51a4 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java @@ -254,7 +254,9 @@ public void testAddTransaction(){ onView(withId(R.id.fab_create_transaction)).perform(click()); onView(withId(R.id.input_transaction_name)).perform(typeText("Lunch")); + Espresso.closeSoftKeyboard(); onView(withId(R.id.input_transaction_amount)).perform(typeText("899")); + Espresso.closeSoftKeyboard(); onView(withId(R.id.input_transaction_type)) .check(matches(allOf(isDisplayed(), withText(R.string.label_receive)))) .perform(click()) @@ -409,7 +411,7 @@ public void testSplitEditor(){ onView(withId(R.id.input_transaction_name)).perform(typeText("Autobalance")); onView(withId(R.id.input_transaction_amount)).perform(typeText("499")); - + Espresso.closeSoftKeyboard(); onView(withId(R.id.btn_split_editor)).perform(click()); onView(withId(R.id.split_list_layout)).check(matches(allOf(isDisplayed(), hasDescendant(withId(R.id.input_split_amount))))); diff --git a/app/src/androidTest/java/org/gnucash/android/test/ui/util/GnucashAndroidTestRunner.java b/app/src/androidTest/java/org/gnucash/android/test/ui/util/GnucashAndroidTestRunner.java index 939b7bb45..40d9691bb 100644 --- a/app/src/androidTest/java/org/gnucash/android/test/ui/util/GnucashAndroidTestRunner.java +++ b/app/src/androidTest/java/org/gnucash/android/test/ui/util/GnucashAndroidTestRunner.java @@ -19,6 +19,7 @@ import android.content.pm.PackageManager; import android.os.Bundle; import android.os.IBinder; +import android.support.multidex.MultiDex; import android.support.test.runner.AndroidJUnitRunner; import android.util.Log; diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 45ec83f68..45e5a6aba 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -107,9 +107,8 @@ android:theme="@style/Theme.GnucashTheme" /> - @@ -120,11 +119,6 @@ - @@ -161,6 +155,14 @@ + + + \ No newline at end of file diff --git a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java index b8327546b..394926963 100644 --- a/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java +++ b/app/src/main/java/org/gnucash/android/app/GnuCashApplication.java @@ -27,6 +27,7 @@ import android.os.Build; import android.os.SystemClock; import android.support.annotation.NonNull; +import android.support.multidex.MultiDexApplication; import android.support.v7.preference.PreferenceManager; import android.util.Log; @@ -66,7 +67,12 @@ * @author Ngewi Fet * */ -public class GnuCashApplication extends Application{ +public class GnuCashApplication extends MultiDexApplication { + + /** + * Authority (domain) for the file provider. Also used in the app manifest + */ + public static final String FILE_PROVIDER_AUTHORITY = BuildConfig.APPLICATION_ID + ".fileprovider"; /** * Lifetime of passcode session diff --git a/app/src/main/java/org/gnucash/android/db/MigrationHelper.java b/app/src/main/java/org/gnucash/android/db/MigrationHelper.java index 74c248694..f5d3805ec 100644 --- a/app/src/main/java/org/gnucash/android/db/MigrationHelper.java +++ b/app/src/main/java/org/gnucash/android/db/MigrationHelper.java @@ -42,7 +42,6 @@ import org.gnucash.android.model.BaseModel; import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; -import org.gnucash.android.model.PeriodType; import org.gnucash.android.model.Recurrence; import org.gnucash.android.model.ScheduledAction; import org.gnucash.android.model.Transaction; @@ -1360,13 +1359,12 @@ static int upgradeDbToVersion13(SQLiteDatabase db){ String uid = cursor.getString(cursor.getColumnIndexOrThrow(ScheduledActionEntry.COLUMN_UID)); long period = cursor.getLong(cursor.getColumnIndexOrThrow("period")); long startTime = cursor.getLong(cursor.getColumnIndexOrThrow(ScheduledActionEntry.COLUMN_START_TIME)); - PeriodType periodType = PeriodType.parse(period); - Recurrence recurrence = new Recurrence(periodType); + Recurrence recurrence = Recurrence.fromLegacyPeriod(period); recurrence.setPeriodStart(new Timestamp(startTime)); contentValues.clear(); contentValues.put(RecurrenceEntry.COLUMN_UID, recurrence.getUID()); - contentValues.put(RecurrenceEntry.COLUMN_MULTIPLIER, recurrence.getPeriodType().getMultiplier()); + contentValues.put(RecurrenceEntry.COLUMN_MULTIPLIER, recurrence.getMultiplier()); contentValues.put(RecurrenceEntry.COLUMN_PERIOD_TYPE, recurrence.getPeriodType().name()); contentValues.put(RecurrenceEntry.COLUMN_PERIOD_START, recurrence.getPeriodStart().toString()); db.insert(RecurrenceEntry.TABLE_NAME, null, contentValues); diff --git a/app/src/main/java/org/gnucash/android/db/adapter/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/adapter/AccountsDbAdapter.java index d37d85b86..273dd908b 100644 --- a/app/src/main/java/org/gnucash/android/db/adapter/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/adapter/AccountsDbAdapter.java @@ -581,12 +581,11 @@ public List getExportableAccounts(Timestamp lastExportTimeStamp){ /** * Retrieves the unique ID of the imbalance account for a particular currency (creates the imbalance account * on demand if necessary) - * @param currency Currency for the imbalance account + * @param commodity Commodity for the imbalance account * @return String unique ID of the account */ - public String getOrCreateImbalanceAccountUID(Currency currency){ - String imbalanceAccountName = getImbalanceAccountName(currency); - Commodity commodity = mCommoditiesDbAdapter.getCommodity(currency.getCurrencyCode()); + public String getOrCreateImbalanceAccountUID(Commodity commodity){ + String imbalanceAccountName = getImbalanceAccountName(commodity); String uid = findAccountUidByFullName(imbalanceAccountName); if (uid == null){ Account account = new Account(imbalanceAccountName, commodity); @@ -605,13 +604,27 @@ public String getOrCreateImbalanceAccountUID(Currency currency){ *

This method will not create the imbalance account if it doesn't exist

* @param currency Currency for the imbalance account * @return GUID of the account or null if the account doesn't exist yet - * @see #getOrCreateImbalanceAccountUID(java.util.Currency) + * @see #getOrCreateImbalanceAccountUID(Commodity) */ public String getImbalanceAccountUID(Currency currency){ String imbalanceAccountName = getImbalanceAccountName(currency); return findAccountUidByFullName(imbalanceAccountName); } + /** + * Returns the GUID of the imbalance account for the commodity + * + *

This method will not create the imbalance account if it doesn't exist

+ * + * @param commodity Commodity for the imbalance account + * @return GUID of the account or null if the account doesn't exist yet + * @see #getOrCreateImbalanceAccountUID(Commodity) + */ + public String getImbalanceAccountUID(Commodity commodity){ + String imbalanceAccountName = getImbalanceAccountName(commodity); + return findAccountUidByFullName(imbalanceAccountName); + } + /** * Creates the account with the specified name and returns its unique identifier. *

If a full hierarchical account name is provided, then the whole hierarchy is created and the @@ -735,6 +748,7 @@ public Cursor fetchAccounts(@Nullable String where, @Nullable String[] whereArgs null, where, whereArgs, null, null, orderBy); } + /** * Returns a Cursor set of accounts which fulfill where *

This method returns the accounts list sorted by the full account name

@@ -749,6 +763,21 @@ public Cursor fetchAccountsOrderedByFullName(String where, String[] whereArgs) { AccountEntry.COLUMN_FULL_NAME + " ASC"); } + /** + * Returns a Cursor set of accounts which fulfill where + *

This method returns the favorite accounts first, sorted by name, and then the other accounts, + * sorted by name.

+ * @param where SQL WHERE statement without the 'WHERE' itself + * @param whereArgs where args + * @return Cursor set of accounts which fulfill where + */ + public Cursor fetchAccountsOrderedByFavoriteAndFullName(String where, String[] whereArgs) { + Log.v(LOG_TAG, "Fetching all accounts from db where " + where + " order by Favorite then Name"); + return mDb.query(AccountEntry.TABLE_NAME, + null, where, whereArgs, null, null, + AccountEntry.COLUMN_FAVORITE + " DESC, " + AccountEntry.COLUMN_FULL_NAME + " ASC"); + } + /** * Returns the balance of an account while taking sub-accounts into consideration * @return Account Balance of an account including sub-accounts @@ -1147,7 +1176,7 @@ public List getAllOpeningBalanceTransactions(){ Transaction transaction = new Transaction(GnuCashApplication.getAppContext().getString(R.string.account_name_opening_balances)); transaction.setNote(getAccountName(accountUID)); - transaction.setCurrencyCode(currencyCode); + transaction.setCommodity(Commodity.getInstance(currencyCode)); TransactionType transactionType = Transaction.getTypeForBalance(getAccountType(accountUID), balance.isNegative()); Split split = new Split(balance.abs(), accountUID); @@ -1176,6 +1205,16 @@ public static String getImbalanceAccountName(Currency currency){ return getImbalanceAccountPrefix() + currency.getCurrencyCode(); } + /** + * Returns the imbalance account where to store transactions which are not double entry. + * + * @param commodity Commodity of the transaction + * @return Imbalance account name + */ + public static String getImbalanceAccountName(Commodity commodity){ + return getImbalanceAccountPrefix() + commodity.getCurrencyCode(); + } + /** * Get the name of the default account for opening balances for the current locale. * For the English locale, it will be "Equity:Opening Balances" diff --git a/app/src/main/java/org/gnucash/android/db/adapter/BooksDbAdapter.java b/app/src/main/java/org/gnucash/android/db/adapter/BooksDbAdapter.java index abbce8027..65e06c950 100644 --- a/app/src/main/java/org/gnucash/android/db/adapter/BooksDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/adapter/BooksDbAdapter.java @@ -31,8 +31,6 @@ import org.gnucash.android.ui.settings.PreferenceActivity; import org.gnucash.android.util.TimestampHelper; -import java.util.List; - /** * Database adapter for creating/modifying book entries */ diff --git a/app/src/main/java/org/gnucash/android/db/adapter/DatabaseAdapter.java b/app/src/main/java/org/gnucash/android/db/adapter/DatabaseAdapter.java index d6de72871..5ebfd32b5 100644 --- a/app/src/main/java/org/gnucash/android/db/adapter/DatabaseAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/adapter/DatabaseAdapter.java @@ -17,8 +17,6 @@ package org.gnucash.android.db.adapter; import android.content.ContentValues; -import android.content.Context; -import android.content.SharedPreferences; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteStatement; @@ -26,7 +24,6 @@ import android.text.TextUtils; import android.util.Log; -import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.db.DatabaseSchema; import org.gnucash.android.db.DatabaseSchema.AccountEntry; import org.gnucash.android.db.DatabaseSchema.CommonColumns; @@ -34,7 +31,6 @@ import org.gnucash.android.db.DatabaseSchema.TransactionEntry; import org.gnucash.android.model.AccountType; import org.gnucash.android.model.BaseModel; -import org.gnucash.android.ui.settings.PreferenceActivity; import org.gnucash.android.util.TimestampHelper; import java.util.ArrayList; diff --git a/app/src/main/java/org/gnucash/android/db/adapter/RecurrenceDbAdapter.java b/app/src/main/java/org/gnucash/android/db/adapter/RecurrenceDbAdapter.java index 0783e58b1..e493d2596 100644 --- a/app/src/main/java/org/gnucash/android/db/adapter/RecurrenceDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/adapter/RecurrenceDbAdapter.java @@ -66,9 +66,9 @@ public Recurrence buildModelInstance(@NonNull Cursor cursor) { String byDays = cursor.getString(cursor.getColumnIndexOrThrow(RecurrenceEntry.COLUMN_BYDAY)); PeriodType periodType = PeriodType.valueOf(type); - periodType.setMultiplier((int) multiplier); Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier((int) multiplier); recurrence.setPeriodStart(Timestamp.valueOf(periodStart)); if (periodEnd != null) recurrence.setPeriodEnd(Timestamp.valueOf(periodEnd)); @@ -82,7 +82,7 @@ public Recurrence buildModelInstance(@NonNull Cursor cursor) { @Override protected @NonNull SQLiteStatement setBindings(@NonNull SQLiteStatement stmt, @NonNull final Recurrence recurrence) { stmt.clearBindings(); - stmt.bindLong(1, recurrence.getPeriodType().getMultiplier()); + stmt.bindLong(1, recurrence.getMultiplier()); stmt.bindString(2, recurrence.getPeriodType().name()); if (!recurrence.getByDays().isEmpty()) stmt.bindString(3, byDaysToString(recurrence.getByDays())); diff --git a/app/src/main/java/org/gnucash/android/db/adapter/TransactionsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/adapter/TransactionsDbAdapter.java index 4facc734c..f86c6fa5b 100644 --- a/app/src/main/java/org/gnucash/android/db/adapter/TransactionsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/adapter/TransactionsDbAdapter.java @@ -105,7 +105,8 @@ public void addRecord(@NonNull Transaction transaction, UpdateMethod updateMetho try { Split imbalanceSplit = transaction.createAutoBalanceSplit(); if (imbalanceSplit != null){ - String imbalanceAccountUID = new AccountsDbAdapter(mDb, this).getOrCreateImbalanceAccountUID(transaction.getCurrency()); + String imbalanceAccountUID = new AccountsDbAdapter(mDb, this) + .getOrCreateImbalanceAccountUID(transaction.getCommodity()); imbalanceSplit.setAccountUID(imbalanceAccountUID); } super.addRecord(transaction, updateMethod); @@ -183,12 +184,7 @@ public long bulkAddRecords(@NonNull List transactionList, UpdateMet stmt.bindLong(3, transaction.getTimeMillis()); stmt.bindLong(4, transaction.isExported() ? 1 : 0); stmt.bindString(5, transaction.getCurrencyCode()); - - Commodity commodity = transaction.getCommodity(); - if (commodity == null) - commodity = mCommoditiesDbAdapter.getCommodity(transaction.getCurrencyCode()); - - stmt.bindString(6, commodity.getUID()); + stmt.bindString(6, transaction.getCommodity().getUID()); stmt.bindString(7, TimestampHelper.getUtcStringFromTimestamp(transaction.getCreatedTimestamp())); if (transaction.getScheduledActionUID() == null) @@ -413,7 +409,6 @@ public Transaction buildModelInstance(@NonNull final Cursor c){ transaction.setExported(c.getInt(c.getColumnIndexOrThrow(TransactionEntry.COLUMN_EXPORTED)) == 1); transaction.setTemplate(c.getInt(c.getColumnIndexOrThrow(TransactionEntry.COLUMN_TEMPLATE)) == 1); String currencyCode = c.getString(c.getColumnIndexOrThrow(TransactionEntry.COLUMN_CURRENCY)); - transaction.setCurrencyCode(currencyCode); transaction.setCommodity(mCommoditiesDbAdapter.getCommodity(currencyCode)); transaction.setScheduledActionUID(c.getString(c.getColumnIndexOrThrow(TransactionEntry.COLUMN_SCHEDX_ACTION_UID))); long transactionID = c.getLong(c.getColumnIndexOrThrow(TransactionEntry._ID)); diff --git a/app/src/main/java/org/gnucash/android/export/DropboxHelper.java b/app/src/main/java/org/gnucash/android/export/DropboxHelper.java new file mode 100644 index 000000000..bb98ea10e --- /dev/null +++ b/app/src/main/java/org/gnucash/android/export/DropboxHelper.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2016 Ngewi Fet + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.gnucash.android.export; + +import android.app.Activity; +import android.content.Context; +import android.content.SharedPreferences; +import android.support.v7.preference.PreferenceManager; + +import com.dropbox.core.DbxRequestConfig; +import com.dropbox.core.android.Auth; +import com.dropbox.core.v2.DbxClientV2; + +import org.gnucash.android.BuildConfig; +import org.gnucash.android.R; +import org.gnucash.android.app.GnuCashApplication; + +/** + * Helper class for commonly used DropBox methods + */ +public class DropboxHelper { + + /** + * DropBox API v2 client for making requests to DropBox + */ + private static DbxClientV2 sDbxClient; + /** + * Retrieves the access token after DropBox OAuth authentication and saves it to preferences file + *

This method should typically by called in the {@link Activity#onResume()} method of the + * Activity or Fragment which called {@link Auth#startOAuth2Authentication(Context, String)} + *

+ * @return Retrieved access token. Could be null if authentication failed or was canceled. + */ + public static String retrieveAndSaveToken(){ + Context context = GnuCashApplication.getAppContext(); + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); + String keyAccessToken = context.getString(R.string.key_dropbox_access_token); + String accessToken = sharedPrefs.getString(keyAccessToken, null); + if (accessToken != null) + return accessToken; + + accessToken = Auth.getOAuth2Token(); + sharedPrefs.edit() + .putString(keyAccessToken, accessToken) + .apply(); + return accessToken; + } + + /** + * Return a DropBox client for making requests + * @return DropBox client for API v2 + */ + public static DbxClientV2 getClient(){ + if (sDbxClient != null) + return sDbxClient; + + Context context = GnuCashApplication.getAppContext(); + String accessToken = PreferenceManager.getDefaultSharedPreferences(context) + .getString(context.getString(R.string.key_dropbox_access_token), null); + if (accessToken == null) + accessToken = Auth.getOAuth2Token(); + + DbxRequestConfig config = new DbxRequestConfig(BuildConfig.APPLICATION_ID); + sDbxClient = new DbxClientV2(config, accessToken); + + return sDbxClient; + } + + /** + * Checks if the app holds an access token for dropbox + * @return {@code true} if token exists, {@code false} otherwise + */ + public static boolean hasToken(){ + Context context = GnuCashApplication.getAppContext(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context); + String accessToken = prefs.getString(context.getString(R.string.key_dropbox_access_token), null); + return accessToken != null; + } +} diff --git a/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java b/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java index f1c0ffb39..0f3648599 100644 --- a/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java +++ b/app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java @@ -30,14 +30,14 @@ import android.os.Build; import android.preference.PreferenceManager; import android.support.annotation.NonNull; +import android.support.v4.content.FileProvider; import android.util.Log; import android.widget.Toast; import com.crashlytics.android.Crashlytics; -import com.dropbox.sync.android.DbxAccountManager; -import com.dropbox.sync.android.DbxFile; -import com.dropbox.sync.android.DbxFileSystem; -import com.dropbox.sync.android.DbxPath; +import com.dropbox.core.v2.DbxClientV2; +import com.dropbox.core.v2.files.FileMetadata; +import com.dropbox.core.v2.files.Metadata; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.drive.Drive; import com.google.android.gms.drive.DriveApi; @@ -144,7 +144,6 @@ protected Boolean doInBackground(ExportParams... params) { mExporter = getExporter(); try { - // FIXME: detect if there aren't transactions to export and inform the user mExportedFiles = mExporter.generateExport(); } catch (final Exception e) { Log.e(TAG, "Error exporting: " + e.getMessage()); @@ -164,12 +163,16 @@ public void run() { return false; } + if (mExportedFiles.isEmpty()) + return false; + try { moveToTarget(); } catch (Exporter.ExporterException e) { Crashlytics.log(Log.ERROR, TAG, "Error sending exported files to target: " + e.getMessage()); return false; } + return true; } @@ -190,12 +193,23 @@ protected void onPostExecute(Boolean exportSuccessful) { } } else { if (mContext instanceof Activity) { - Toast.makeText(mContext, - mContext.getString(R.string.toast_export_error, mExportParams.getExportFormat().name()), - Toast.LENGTH_LONG).show(); + dismissProgressDialog(); + if (mExportedFiles.isEmpty()) { + Toast.makeText(mContext, + R.string.toast_no_transactions_to_export, + Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(mContext, + mContext.getString(R.string.toast_export_error, mExportParams.getExportFormat().name()), + Toast.LENGTH_LONG).show(); + } } } + dismissProgressDialog(); + } + + private void dismissProgressDialog() { if (mContext instanceof Activity) { if (mProgressDialog != null && mProgressDialog.isShowing()) mProgressDialog.dismiss(); @@ -203,6 +217,10 @@ protected void onPostExecute(Boolean exportSuccessful) { } } + /** + * Returns an exporter corresponding to the user settings. + * @return Object of one of {@link QifExporter}, {@link OfxExporter} or {@link GncXmlExporter} + */ private Exporter getExporter() { switch (mExportParams.getExportFormat()) { case QIF: @@ -217,11 +235,14 @@ private Exporter getExporter() { } } + /** + * Moves the generated export files to the target specified by the user + * @throws Exporter.ExporterException if the move fails + */ private void moveToTarget() throws Exporter.ExporterException { switch (mExportParams.getExportTarget()) { case SHARING: - List sdCardExportedFiles = moveExportToSDCard(); - shareFiles(sdCardExportedFiles); + shareFiles(mExportedFiles); break; case DROPBOX: @@ -299,26 +320,32 @@ private void moveExportToGoogleDrive() throws Exporter.ExporterException { Log.i(TAG, "Created file with id: " + driveFileResult.getDriveFile().getDriveId()); } - private void moveExportToDropbox() throws Exporter.ExporterException { - Log.i(TAG, "Copying exported file to DropBox"); - String dropboxAppKey = mContext.getString(R.string.dropbox_app_key, BackupPreferenceFragment.DROPBOX_APP_KEY); - String dropboxAppSecret = mContext.getString(R.string.dropbox_app_secret, BackupPreferenceFragment.DROPBOX_APP_SECRET); - DbxAccountManager mDbxAcctMgr = DbxAccountManager.getInstance(mContext.getApplicationContext(), - dropboxAppKey, dropboxAppSecret); - DbxFile dbExportFile = null; - try { - DbxFileSystem dbxFileSystem = DbxFileSystem.forAccount(mDbxAcctMgr.getLinkedAccount()); - for (String exportedFilePath : mExportedFiles) { - File exportedFile = new File(exportedFilePath); - dbExportFile = dbxFileSystem.create(new DbxPath(exportedFile.getName())); - dbExportFile.writeFromExistingFile(exportedFile, false); - exportedFile.delete(); - } - } catch (IOException e) { - throw new Exporter.ExporterException(mExportParams); - } finally { - if (dbExportFile != null) { - dbExportFile.close(); + /** + * Move the exported files (in the cache directory) to Dropbox + */ + private void moveExportToDropbox() { + Log.i(TAG, "Uploading exported files to DropBox"); + + DbxClientV2 dbxClient = DropboxHelper.getClient(); + + for (String exportedFilePath : mExportedFiles) { + File exportedFile = new File(exportedFilePath); + FileInputStream inputStream = null; + try { + inputStream = new FileInputStream(exportedFile); + List entries = dbxClient.files().listFolder("").getEntries(); + + FileMetadata metadata = dbxClient.files() + .uploadBuilder("/" + exportedFile.getName()) + .uploadAndFinish(inputStream); + Log.i(TAG, "Successfully uploaded file " + metadata.getName() + " to DropBox"); + inputStream.close(); + exportedFile.delete(); //delete file to prevent cache accumulation + } catch (IOException e) { + Crashlytics.logException(e); + Log.e(TAG, e.getMessage()); + } catch (com.dropbox.core.DbxException e) { + e.printStackTrace(); } } } @@ -426,8 +453,8 @@ private void shareFiles(List paths) { shareIntent.setType("text/xml"); ArrayList exportFiles = convertFilePathsToUris(paths); -// shareIntent.putExtra(Intent.EXTRA_STREAM, exportFiles); shareIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, exportFiles); + shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); shareIntent.putExtra(Intent.EXTRA_SUBJECT, mContext.getString(R.string.title_export_email, mExportParams.getExportFormat().name())); @@ -467,9 +494,8 @@ private ArrayList convertFilePathsToUris(List paths) { for (String path : paths) { File file = new File(path); - file.setReadable(true, false); - exportFiles.add(Uri.fromFile(file)); -// exportFiles.add(Uri.parse("file://" + file)); + Uri contentUri = FileProvider.getUriForFile(GnuCashApplication.getAppContext(), GnuCashApplication.FILE_PROVIDER_AUTHORITY, file); + exportFiles.add(contentUri); } return exportFiles; } diff --git a/app/src/main/java/org/gnucash/android/export/Exporter.java b/app/src/main/java/org/gnucash/android/export/Exporter.java index c79c9b426..6e000d036 100644 --- a/app/src/main/java/org/gnucash/android/export/Exporter.java +++ b/app/src/main/java/org/gnucash/android/export/Exporter.java @@ -38,7 +38,6 @@ 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 java.io.File; import java.text.ParseException; @@ -254,7 +253,7 @@ public String getExportMimeType(){ return "text/plain"; } - public static class ExporterException extends Exception { + public static class ExporterException extends RuntimeException{ public ExporterException(ExportParams params){ super("Failed to generate export with parameters: " + params.toString()); diff --git a/app/src/main/java/org/gnucash/android/export/ofx/OfxExporter.java b/app/src/main/java/org/gnucash/android/export/ofx/OfxExporter.java index c7babfdb5..0c1d0e386 100644 --- a/app/src/main/java/org/gnucash/android/export/ofx/OfxExporter.java +++ b/app/src/main/java/org/gnucash/android/export/ofx/OfxExporter.java @@ -130,8 +130,6 @@ private void generateOfx(Document doc, Element parent){ * @throws ExporterException */ private String generateOfxExport() throws ExporterException { - mAccountsList = mAccountsDbAdapter.getExportableAccounts(mExportParams.getExportStartTime()); - DocumentBuilderFactory docFactory = DocumentBuilderFactory .newInstance(); DocumentBuilder docBuilder; @@ -169,6 +167,10 @@ private String generateOfxExport() throws ExporterException { @Override public List generateExport() throws ExporterException { + mAccountsList = mAccountsDbAdapter.getExportableAccounts(mExportParams.getExportStartTime()); + if (mAccountsList.isEmpty()) + return new ArrayList<>(); // Nothing to export, so no files generated + BufferedWriter writer = null; try { diff --git a/app/src/main/java/org/gnucash/android/export/xml/GncXmlExporter.java b/app/src/main/java/org/gnucash/android/export/xml/GncXmlExporter.java index 7a3105ab4..c96420275 100644 --- a/app/src/main/java/org/gnucash/android/export/xml/GncXmlExporter.java +++ b/app/src/main/java/org/gnucash/android/export/xml/GncXmlExporter.java @@ -23,10 +23,9 @@ import com.crashlytics.android.Crashlytics; -import org.gnucash.android.app.GnuCashApplication; +import org.gnucash.android.db.DatabaseSchema; import org.gnucash.android.db.adapter.BooksDbAdapter; import org.gnucash.android.db.adapter.CommoditiesDbAdapter; -import org.gnucash.android.db.DatabaseSchema; import org.gnucash.android.db.adapter.RecurrenceDbAdapter; import org.gnucash.android.db.adapter.TransactionsDbAdapter; import org.gnucash.android.export.ExportFormat; @@ -36,9 +35,9 @@ import org.gnucash.android.model.AccountType; import org.gnucash.android.model.BaseModel; import org.gnucash.android.model.Book; -import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Budget; import org.gnucash.android.model.BudgetAmount; +import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; import org.gnucash.android.model.PeriodType; import org.gnucash.android.model.Recurrence; @@ -49,7 +48,6 @@ import org.xmlpull.v1.XmlSerializer; import java.io.BufferedOutputStream; -import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; @@ -704,7 +702,7 @@ private void exportPrices(XmlSerializer xmlSerializer) throws IOException { private void exportRecurrence(XmlSerializer xmlSerializer, Recurrence recurrence) throws IOException{ PeriodType periodType = recurrence.getPeriodType(); xmlSerializer.startTag(null, GncXmlHelper.TAG_RX_MULT); - xmlSerializer.text(String.valueOf(periodType.getMultiplier())); + xmlSerializer.text(String.valueOf(recurrence.getMultiplier())); xmlSerializer.endTag(null, GncXmlHelper.TAG_RX_MULT); xmlSerializer.startTag(null, GncXmlHelper.TAG_RX_PERIOD_TYPE); xmlSerializer.text(periodType.name().toLowerCase()); @@ -812,6 +810,11 @@ public void generateExport(Writer writer) throws ExporterException { String[] namespaces = new String[]{"gnc", "act", "book", "cd", "cmdty", "price", "slot", "split", "trn", "ts", "sx", "bgt", "recurrence"}; XmlSerializer xmlSerializer = XmlPullParserFactory.newInstance().newSerializer(); + try { + xmlSerializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true); + } catch (IllegalStateException e) { + // Feature not supported. No problem + } xmlSerializer.setOutput(writer); xmlSerializer.startDocument("utf-8", true); // root tag diff --git a/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java b/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java index 1d7938eb8..38a97a663 100644 --- a/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java +++ b/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java @@ -438,8 +438,8 @@ public void endElement(String uri, String localName, String qualifiedName) throw break; case GncXmlHelper.TAG_COMMODITY_ID: String currencyCode = mISO4217Currency ? characterString : NO_CURRENCY_CODE; + Commodity commodity = mCommoditiesDbAdapter.getCommodity(currencyCode); if (mAccount != null) { - Commodity commodity = mCommoditiesDbAdapter.getCommodity(currencyCode); if (commodity != null) { mAccount.setCommodity(commodity); } else { @@ -453,7 +453,7 @@ public void endElement(String uri, String localName, String qualifiedName) throw } } if (mTransaction != null) { - mTransaction.setCurrencyCode(currencyCode); + mTransaction.setCommodity(commodity); } if (mPrice != null) { if (mPriceCommodity) { @@ -675,7 +675,7 @@ public void endElement(String uri, String localName, String qualifiedName) throw //the split amount uses the account currency mSplit.setQuantity(new Money(mQuantity, getCommodityForAccount(characterString))); //the split value uses the transaction currency - mSplit.setValue(new Money(mValue, mCommoditiesDbAdapter.getCommodity(mTransaction.getCurrency().getCurrencyCode()))); + mSplit.setValue(new Money(mValue, mTransaction.getCommodity())); mSplit.setAccountUID(characterString); } else { if (!mIgnoreTemplateTransaction) @@ -737,8 +737,8 @@ public void endElement(String uri, String localName, String qualifiedName) throw case GncXmlHelper.TAG_RX_PERIOD_TYPE: try { PeriodType periodType = PeriodType.valueOf(characterString.toUpperCase()); - periodType.setMultiplier(mRecurrenceMultiplier); mRecurrence.setPeriodType(periodType); + mRecurrence.setMultiplier(mRecurrenceMultiplier); } catch (IllegalArgumentException ex){ //the period type constant is not supported String msg = "Unsupported period constant: " + characterString; Log.e(LOG_TAG, msg); @@ -1050,11 +1050,16 @@ private Commodity getCommodityForAccount(String accountUID){ */ private void handleEndOfTemplateNumericSlot(String characterString, TransactionType splitType) { try { - BigDecimal amountBigD = GncXmlHelper.parseSplitAmount(characterString); - Money amount = new Money(amountBigD, getCommodityForAccount(mSplit.getAccountUID())); - mSplit.setValue(amount.abs()); - mSplit.setType(splitType); - mIgnoreTemplateTransaction = false; //we have successfully parsed an amount + // HACK: Check for bug #562. If a value has already been set, ignore the one just read + if (mSplit.getValue().equals( + new Money(BigDecimal.ZERO, mSplit.getValue().getCommodity()))) { + BigDecimal amountBigD = GncXmlHelper.parseSplitAmount(characterString); + Money amount = new Money(amountBigD, getCommodityForAccount(mSplit.getAccountUID())); + + mSplit.setValue(amount.abs()); + mSplit.setType(splitType); + mIgnoreTemplateTransaction = false; //we have successfully parsed an amount + } } catch (NumberFormatException | ParseException e) { String msg = "Error parsing template credit split amount " + characterString; Log.e(LOG_TAG, msg + "\n" + e.getMessage()); diff --git a/app/src/main/java/org/gnucash/android/model/Budget.java b/app/src/main/java/org/gnucash/android/model/Budget.java index db199b366..add151287 100644 --- a/app/src/main/java/org/gnucash/android/model/Budget.java +++ b/app/src/main/java/org/gnucash/android/model/Budget.java @@ -202,7 +202,7 @@ public long getNumberOfPeriods() { */ public long getStartofCurrentPeriod(){ LocalDateTime localDate = new LocalDateTime(); - int interval = mRecurrence.getPeriodType().getMultiplier(); + int interval = mRecurrence.getMultiplier(); switch (mRecurrence.getPeriodType()){ case DAY: localDate = localDate.millisOfDay().withMinimumValue().plusDays(interval); @@ -226,7 +226,7 @@ public long getStartofCurrentPeriod(){ */ public long getEndOfCurrentPeriod(){ LocalDateTime localDate = new LocalDateTime(); - int interval = mRecurrence.getPeriodType().getMultiplier(); + int interval = mRecurrence.getMultiplier(); switch (mRecurrence.getPeriodType()){ case DAY: localDate = localDate.millisOfDay().withMaximumValue().plusDays(interval); @@ -246,7 +246,7 @@ public long getEndOfCurrentPeriod(){ public long getStartOfPeriod(int periodNum){ LocalDateTime localDate = new LocalDateTime(mRecurrence.getPeriodStart().getTime()); - int interval = mRecurrence.getPeriodType().getMultiplier() * periodNum; + int interval = mRecurrence.getMultiplier() * periodNum; switch (mRecurrence.getPeriodType()){ case DAY: localDate = localDate.millisOfDay().withMinimumValue().plusDays(interval); @@ -271,7 +271,7 @@ public long getStartOfPeriod(int periodNum){ */ public long getEndOfPeriod(int periodNum){ LocalDateTime localDate = new LocalDateTime(); - int interval = mRecurrence.getPeriodType().getMultiplier() * periodNum; + int interval = mRecurrence.getMultiplier() * periodNum; switch (mRecurrence.getPeriodType()){ case DAY: localDate = localDate.millisOfDay().withMaximumValue().plusDays(interval); diff --git a/app/src/main/java/org/gnucash/android/model/Money.java b/app/src/main/java/org/gnucash/android/model/Money.java index ef7cec86d..1f7fbfaf4 100644 --- a/app/src/main/java/org/gnucash/android/model/Money.java +++ b/app/src/main/java/org/gnucash/android/model/Money.java @@ -114,7 +114,7 @@ public Money(BigDecimal amount, Commodity commodity){ /** * Overloaded constructor. * Accepts strings as arguments and parses them to create the Money object - * @param amount Numrical value of the Money + * @param amount Numerical value of the Money * @param currencyCode Currency code as specified by ISO 4217 */ public Money(String amount, String currencyCode){ @@ -155,14 +155,6 @@ public static Money createZeroInstance(@NonNull String currencyCode){ return new Money(BigDecimal.ZERO, commodity); } - /** - * Returns the currency of the money object - * @return {@link Currency} of the money value - */ - public Currency getCurrency() { - return Currency.getInstance(mCommodity.getCurrencyCode()); - } - /** * Returns the commodity used by the Money * @return Instance of commodity @@ -277,15 +269,13 @@ public String asString(){ public String formattedString(Locale locale){ NumberFormat currencyFormat = NumberFormat.getCurrencyInstance(locale); - Currency currency = Currency.getInstance(mCommodity.getCurrencyCode()); String symbol; + //if we want to show US Dollars for locales which also use Dollars, for example, Canada if (mCommodity.equals(Commodity.USD) && !locale.equals(Locale.US)) { symbol = "US$"; - } else if (mCommodity.equals(Commodity.EUR)) { - symbol = currency.getSymbol(Locale.GERMANY); //euro currency is pretty unique around the world } else { - symbol = currency.getSymbol(Locale.US); // US locale has the best symbol formatting table. + symbol = mCommodity.getSymbol(); } DecimalFormatSymbols decimalFormatSymbols = ((DecimalFormat)currencyFormat).getDecimalFormatSymbols(); decimalFormatSymbols.setCurrencySymbol(symbol); diff --git a/app/src/main/java/org/gnucash/android/model/PeriodType.java b/app/src/main/java/org/gnucash/android/model/PeriodType.java index 06b13cc4b..882620be3 100644 --- a/app/src/main/java/org/gnucash/android/model/PeriodType.java +++ b/app/src/main/java/org/gnucash/android/model/PeriodType.java @@ -16,12 +16,6 @@ package org.gnucash.android.model; -import android.content.res.Resources; - -import org.gnucash.android.R; -import org.gnucash.android.app.GnuCashApplication; -import org.gnucash.android.ui.util.RecurrenceParser; - import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -34,63 +28,6 @@ public enum PeriodType { DAY, WEEK, MONTH, YEAR; // TODO: 22.10.2015 add support for hourly - int mMultiplier = 1; //multiplier for the period type - - /** - * Computes the {@link PeriodType} for a given {@code period} - * @param period Period in milliseconds since Epoch - * @return PeriodType corresponding to the period - */ - public static PeriodType parse(long period){ - PeriodType periodType = DAY; - int result = (int) (period/ RecurrenceParser.YEAR_MILLIS); - if (result > 0) { - periodType = YEAR; - periodType.setMultiplier(result); - return periodType; - } - - result = (int) (period/RecurrenceParser.MONTH_MILLIS); - if (result > 0) { - periodType = MONTH; - periodType.setMultiplier(result); - return periodType; - } - - result = (int) (period/RecurrenceParser.WEEK_MILLIS); - if (result > 0) { - periodType = WEEK; - periodType.setMultiplier(result); - return periodType; - } - - result = (int) (period/RecurrenceParser.DAY_MILLIS); - if (result > 0) { - periodType = DAY; - periodType.setMultiplier(result); - return periodType; - } - - return periodType; - } - - /** - * Sets the multiplier for this period type - * e.g. bi-weekly actions have period type {@link PeriodType#WEEK} and multiplier 2 - * @param multiplier Multiplier for this period type - */ - public void setMultiplier(int multiplier){ - mMultiplier = multiplier; - } - - /** - * Returns the multiplier for this period type. The default multiplier is 1. - * e.g. bi-weekly actions have period type {@link PeriodType#WEEK} and multiplier 2 - * @return Multiplier for this period type - */ - public int getMultiplier(){ - return mMultiplier; - } /** * Returns the frequency description of this period type. @@ -112,27 +49,6 @@ public String getFrequencyDescription() { } } - /** - * Returns a localized string describing this period type's frequency. - * @return String describing period type - */ - public String getFrequencyRepeatString(){ - Resources res = GnuCashApplication.getAppContext().getResources(); - //todo: take multiplier into account here - switch (this) { - case DAY: - return res.getQuantityString(R.plurals.label_every_x_days, mMultiplier, mMultiplier); - case WEEK: - return res.getQuantityString(R.plurals.label_every_x_weeks, mMultiplier, mMultiplier); - case MONTH: - return res.getQuantityString(R.plurals.label_every_x_months, mMultiplier, mMultiplier); - case YEAR: - return res.getQuantityString(R.plurals.label_every_x_years, mMultiplier, mMultiplier); - default: - return ""; - } - } - /** * Returns the parts of the recurrence rule which describe the day or month on which to run the * scheduled transaction. These parts are the BYxxx @@ -155,6 +71,4 @@ public String getByParts(long startTime){ } return partString; } - - } diff --git a/app/src/main/java/org/gnucash/android/model/Recurrence.java b/app/src/main/java/org/gnucash/android/model/Recurrence.java index 830bb0523..9a5f94e87 100644 --- a/app/src/main/java/org/gnucash/android/model/Recurrence.java +++ b/app/src/main/java/org/gnucash/android/model/Recurrence.java @@ -17,6 +17,7 @@ package org.gnucash.android.model; import android.content.Context; +import android.content.res.Resources; import android.support.annotation.NonNull; import org.gnucash.android.R; @@ -63,6 +64,8 @@ public class Recurrence extends BaseModel { */ private List mByDays = Collections.emptyList(); + private int mMultiplier = 1; //multiplier for the period type + public Recurrence(@NonNull PeriodType periodType){ setPeriodType(periodType); mPeriodStart = new Timestamp(System.currentTimeMillis()); @@ -124,7 +127,7 @@ public long getPeriod(){ baseMillis = RecurrenceParser.YEAR_MILLIS; break; } - return mPeriodType.getMultiplier() * baseMillis; + return mMultiplier * baseMillis; } /** @@ -132,12 +135,14 @@ public long getPeriod(){ * @return String description of repeat schedule */ public String getRepeatString(){ - StringBuilder repeatBuilder = new StringBuilder(mPeriodType.getFrequencyRepeatString()); + StringBuilder repeatBuilder = new StringBuilder(getFrequencyRepeatString()); Context context = GnuCashApplication.getAppContext(); + String dayOfWeek = new SimpleDateFormat("EEEE", GnuCashApplication.getDefaultLocale()) + .format(new Date(mPeriodStart.getTime())); if (mPeriodType == PeriodType.WEEK) { repeatBuilder.append(" "). - append(context.getString(R.string.repeat_on_weekday, getDaysOfWeekString())); + append(context.getString(R.string.repeat_on_weekday, dayOfWeek)); } if (mPeriodEnd != null){ @@ -148,30 +153,11 @@ public String getRepeatString(){ } /** - * Returns a string with the days of the week set in the recurrence separated by commas. - * @return string with the days of the week set in the recurrence separated by commas. + * Creates an RFC 2445 string which describes this recurring event. + *

See http://recurrance.sourceforge.net/

+ *

The output of this method is not meant for human consumption

+ * @return String describing event */ - private @NonNull String getDaysOfWeekString() { - // XXX: mByDays should never be empty with PeriodType.WEEK, but we don't enforce it yet - if (mByDays.isEmpty()) - return ""; - StringBuilder daysOfWeekString = new StringBuilder(); - Calendar calendar = Calendar.getInstance(); - DateFormat dayOfWeekFormatter = - new SimpleDateFormat("EEEE", GnuCashApplication.getDefaultLocale()); - for (int day : mByDays) { - calendar.set(Calendar.DAY_OF_WEEK, day); - daysOfWeekString.append(dayOfWeekFormatter.format(calendar.getTime())).append(", "); - } - return daysOfWeekString.substring(0, daysOfWeekString.length()-2); - } - - /** - * Creates an RFC 2445 string which describes this recurring event. - *

See http://recurrance.sourceforge.net/

- *

The output of this method is not meant for human consumption

- * @return String describing event - */ public String getRuleString(){ String separator = ";"; @@ -189,7 +175,7 @@ public String getRuleString(){ ruleBuilder.append("FREQ=").append(mPeriodType.getFrequencyDescription()).append(separator); - ruleBuilder.append("INTERVAL=").append(mPeriodType.getMultiplier()).append(separator); + ruleBuilder.append("INTERVAL=").append(mMultiplier).append(separator); if (getCount() > 0) ruleBuilder.append("COUNT=").append(getCount()).append(separator); ruleBuilder.append(mPeriodType.getByParts(mPeriodStart.getTime())).append(separator); @@ -203,7 +189,7 @@ public String getRuleString(){ */ public int getDaysLeftInCurrentPeriod(){ LocalDate startDate = new LocalDate(System.currentTimeMillis()); - int interval = mPeriodType.getMultiplier() - 1; + int interval = mMultiplier - 1; LocalDate endDate = null; switch (mPeriodType){ case DAY: @@ -232,7 +218,7 @@ public int getDaysLeftInCurrentPeriod(){ public int getNumberOfPeriods(int numberOfPeriods) { LocalDate startDate = new LocalDate(mPeriodStart.getTime()); LocalDate endDate; - int interval = mPeriodType.getMultiplier(); + int interval = mMultiplier; //// TODO: 15.08.2016 Why do we add the number of periods. maybe rename method or param switch (mPeriodType){ @@ -298,14 +284,14 @@ public void setByDays(@NonNull List byDays){ /** * Computes the number of occurrences of this recurrences between start and end date - *

If there is no end date, it returns -1

+ *

If there is no end date or the PeriodType is unknown, it returns -1

* @return Number of occurrences, or -1 if there is no end date */ public int getCount(){ if (mPeriodEnd == null) return -1; - int multiple = mPeriodType.getMultiplier(); + int multiple = mMultiplier; ReadablePeriod jodaPeriod; switch (mPeriodType){ case DAY: @@ -334,7 +320,7 @@ public int getCount(){ /* //this solution does not use looping, but is not very accurate - int multiplier = mPeriodType.getMultiplier(); + int multiplier = mMultiplier; LocalDateTime startDate = new LocalDateTime(mPeriodStart.getTime()); LocalDateTime endDate = new LocalDateTime(mPeriodEnd.getTime()); switch (mPeriodType){ @@ -359,7 +345,7 @@ public int getCount(){ public void setPeriodEnd(int numberOfOccurences){ LocalDateTime localDate = new LocalDateTime(mPeriodStart.getTime()); LocalDateTime endDate; - int occurrenceDuration = numberOfOccurences * mPeriodType.getMultiplier(); + int occurrenceDuration = numberOfOccurences * mMultiplier; switch (mPeriodType){ case DAY: endDate = localDate.plusDays(occurrenceDuration); @@ -393,4 +379,84 @@ public Timestamp getPeriodEnd(){ public void setPeriodEnd(Timestamp endTimestamp){ mPeriodEnd = endTimestamp; } + + /** + * Returns the multiplier for the period type. The default multiplier is 1. + * e.g. bi-weekly actions have period type {@link PeriodType#WEEK} and multiplier 2. + * + * @return Multiplier for the period type + */ + public int getMultiplier(){ + return mMultiplier; + } + + /** + * Sets the multiplier for the period type. + * e.g. bi-weekly actions have period type {@link PeriodType#WEEK} and multiplier 2. + * + * @param multiplier Multiplier for the period type + */ + public void setMultiplier(int multiplier){ + mMultiplier = multiplier; + } + + /** + * Returns a localized string describing the period type's frequency. + * + * @return String describing the period type + */ + private String getFrequencyRepeatString(){ + Resources res = GnuCashApplication.getAppContext().getResources(); + //todo: take multiplier into account here + switch (mPeriodType) { + case DAY: + return res.getQuantityString(R.plurals.label_every_x_days, mMultiplier, mMultiplier); + case WEEK: + return res.getQuantityString(R.plurals.label_every_x_weeks, mMultiplier, mMultiplier); + case MONTH: + return res.getQuantityString(R.plurals.label_every_x_months, mMultiplier, mMultiplier); + case YEAR: + return res.getQuantityString(R.plurals.label_every_x_years, mMultiplier, mMultiplier); + default: + return ""; + } + } + + /** + * Returns a new {@link Recurrence} with the {@link PeriodType} specified in the old format. + * + * @param period Period in milliseconds since Epoch (old format to define a period) + * @return Recurrence with the specified period. + */ + public static Recurrence fromLegacyPeriod(long period) { + int result = (int) (period/RecurrenceParser.YEAR_MILLIS); + if (result > 0) { + Recurrence recurrence = new Recurrence(PeriodType.YEAR); + recurrence.setMultiplier(result); + return recurrence; + } + + result = (int) (period/RecurrenceParser.MONTH_MILLIS); + if (result > 0) { + Recurrence recurrence = new Recurrence(PeriodType.MONTH); + recurrence.setMultiplier(result); + return recurrence; + } + + result = (int) (period/RecurrenceParser.WEEK_MILLIS); + if (result > 0) { + Recurrence recurrence = new Recurrence(PeriodType.WEEK); + recurrence.setMultiplier(result); + return recurrence; + } + + result = (int) (period/RecurrenceParser.DAY_MILLIS); + if (result > 0) { + Recurrence recurrence = new Recurrence(PeriodType.DAY); + recurrence.setMultiplier(result); + return recurrence; + } + + return new Recurrence(PeriodType.DAY); + } } diff --git a/app/src/main/java/org/gnucash/android/model/ScheduledAction.java b/app/src/main/java/org/gnucash/android/model/ScheduledAction.java index ff27fc76d..b8f49219a 100644 --- a/app/src/main/java/org/gnucash/android/model/ScheduledAction.java +++ b/app/src/main/java/org/gnucash/android/model/ScheduledAction.java @@ -20,12 +20,9 @@ import org.gnucash.android.R; import org.gnucash.android.app.GnuCashApplication; -import org.joda.time.DateTime; -import org.joda.time.LocalDate; import org.joda.time.LocalDateTime; import java.sql.Timestamp; -import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; @@ -151,7 +148,7 @@ public long getTimeOfLastSchedule(){ return -1; LocalDateTime startTime = LocalDateTime.fromDateFields(new Date(mStartDate)); - int multiplier = mRecurrence.getPeriodType().getMultiplier(); + int multiplier = mRecurrence.getMultiplier(); int factor = (mExecutionCount-1) * multiplier; switch (mRecurrence.getPeriodType()){ @@ -214,7 +211,7 @@ private long computeNextScheduledExecutionTimeStartingAt(long startTime) { return mStartDate; } - int multiplier = mRecurrence.getPeriodType().getMultiplier(); + int multiplier = mRecurrence.getMultiplier(); LocalDateTime nextScheduledExecution = LocalDateTime.fromDateFields(new Date(startTime)); switch (mRecurrence.getPeriodType()) { case DAY: @@ -501,8 +498,8 @@ public Recurrence getRecurrence() { * @see #setRecurrence(Recurrence) */ public void setRecurrence(PeriodType periodType, int ordinal){ - periodType.setMultiplier(ordinal); Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier(ordinal); setRecurrence(recurrence); } @@ -539,7 +536,7 @@ public void setRecurrence(@NonNull Recurrence recurrence) { public static ScheduledAction parseScheduledAction(Transaction transaction, long period){ ScheduledAction scheduledAction = new ScheduledAction(ActionType.TRANSACTION); scheduledAction.mActionUID = transaction.getUID(); - Recurrence recurrence = new Recurrence(PeriodType.parse(period)); + Recurrence recurrence = Recurrence.fromLegacyPeriod(period); scheduledAction.setRecurrence(recurrence); return scheduledAction; } diff --git a/app/src/main/java/org/gnucash/android/model/Split.java b/app/src/main/java/org/gnucash/android/model/Split.java index a3101e474..07477a407 100644 --- a/app/src/main/java/org/gnucash/android/model/Split.java +++ b/app/src/main/java/org/gnucash/android/model/Split.java @@ -392,8 +392,9 @@ public String toString() { public String toCsv(){ String sep = ";"; //TODO: add reconciled state and date - String splitString = getUID() + sep + mValue.getNumerator() + sep + mValue.getDenominator() + sep + mValue.getCurrency().getCurrencyCode() + sep - + mQuantity.getNumerator() + sep + mQuantity.getDenominator() + sep + mQuantity.getCurrency().getCurrencyCode() + String splitString = getUID() + sep + mValue.getNumerator() + sep + mValue.getDenominator() + + sep + mValue.getCommodity().getCurrencyCode() + sep + mQuantity.getNumerator() + + sep + mQuantity.getDenominator() + sep + mQuantity.getCommodity().getCurrencyCode() + sep + mTransactionUID + sep + mAccountUID + sep + mSplitType.name(); if (mMemo != null){ splitString = splitString + sep + mMemo; diff --git a/app/src/main/java/org/gnucash/android/model/Transaction.java b/app/src/main/java/org/gnucash/android/model/Transaction.java index 7ff34aa65..2dc7b10dd 100644 --- a/app/src/main/java/org/gnucash/android/model/Transaction.java +++ b/app/src/main/java/org/gnucash/android/model/Transaction.java @@ -17,6 +17,7 @@ package org.gnucash.android.model; import android.content.Intent; +import android.support.annotation.NonNull; import org.gnucash.android.BuildConfig; import org.gnucash.android.db.adapter.AccountsDbAdapter; @@ -26,7 +27,6 @@ import org.w3c.dom.Element; import java.util.ArrayList; -import java.util.Currency; import java.util.Date; import java.util.List; @@ -80,11 +80,6 @@ public class Transaction extends BaseModel{ */ public static final String EXTRA_SPLITS = "org.gnucash.android.extra.transaction.splits"; - /** - * Currency used by splits in this transaction - */ - private String mCurrencyCode = Money.DEFAULT_CURRENCY_CODE; - /** * GUID of commodity associated with this transaction */ @@ -150,7 +145,7 @@ public Transaction(Transaction transaction, boolean generateNewUID){ setDescription(transaction.getDescription()); setNote(transaction.getNote()); setTime(transaction.getTimeMillis()); - mCurrencyCode = transaction.mCurrencyCode; + setCommodity(transaction.getCommodity()); //exported flag is left at default value of false for (Split split : transaction.mSplitList) { @@ -181,8 +176,9 @@ private void initDefaults(){ public Split createAutoBalanceSplit(){ Money imbalance = getImbalance(); //returns imbalance of 0 for multicurrency transactions if (!imbalance.isAmountZero()){ - Split split = new Split(imbalance.negate(), mCurrencyCode); //yes, this is on purpose - //the account UID is set to the currency. This should be overridden before saving to db + // yes, this is on purpose the account UID is set to the currency. + // This should be overridden before saving to db + Split split = new Split(imbalance.negate(), mCommodity.getCurrencyCode()); addSplit(split); return split; } @@ -266,13 +262,13 @@ public Money getBalance(String accountUID){ * @return Money imbalance of the transaction or zero if it is a multi-currency transaction */ public Money getImbalance(){ - Money imbalance = Money.createZeroInstance(mCurrencyCode); + Money imbalance = Money.createZeroInstance(mCommodity.getCurrencyCode()); for (Split split : mSplitList) { - if (!split.getQuantity().getCurrency().getCurrencyCode().equals(mCurrencyCode)) { + if (!split.getQuantity().getCommodity().equals(mCommodity)) { // this may happen when importing XML exported from GNCA before 2.0.0 // these transactions should only be imported from XML exported from GNC desktop // so imbalance split should not be generated for them - return Money.createZeroInstance(mCurrencyCode); + return Money.createZeroInstance(mCommodity.getCurrencyCode()); } Money amount = split.getValue().abs(); if (split.getType() == TransactionType.DEBIT) @@ -295,16 +291,15 @@ public Money getImbalance(){ public static Money computeBalance(String accountUID, List splitList) { AccountsDbAdapter accountsDbAdapter = AccountsDbAdapter.getInstance(); AccountType accountType = accountsDbAdapter.getAccountType(accountUID); - String currencyCode = accountsDbAdapter.getAccountCurrencyCode(accountUID); - Currency accountCurrency = Currency.getInstance(currencyCode); + String accountCurrencyCode = accountsDbAdapter.getAccountCurrencyCode(accountUID); boolean isDebitAccount = accountType.hasDebitNormalBalance(); - Money balance = Money.createZeroInstance(currencyCode); + Money balance = Money.createZeroInstance(accountCurrencyCode); for (Split split : splitList) { if (!split.getAccountUID().equals(accountUID)) continue; Money absAmount; - if (split.getValue().getCurrency() == accountCurrency){ + if (split.getValue().getCommodity().getCurrencyCode().equals(accountCurrencyCode)){ absAmount = split.getValue().abs(); } else { //if this split belongs to the account, then either its value or quantity is in the account currency absAmount = split.getQuantity().abs(); @@ -332,33 +327,14 @@ public static Money computeBalance(String accountUID, List splitList) { * @return ISO 4217 currency code string */ public String getCurrencyCode() { - return mCurrencyCode; - } - - /** - * Sets the ISO 4217 currency code used by this transaction - *

The currency remains in the object model and is not persisted to the database - * Transactions always use the currency of their accounts.

- * @param currencyCode String with ISO 4217 currency code - */ - public void setCurrencyCode(String currencyCode) { - this.mCurrencyCode = currencyCode; - } - - /** - * Returns the {@link java.util.Currency} used by this transaction - * @return Currency of the transaction - * @see #getCurrencyCode() - */ - public Currency getCurrency(){ - return Currency.getInstance(this.mCurrencyCode); + return mCommodity.getCurrencyCode(); } /** * Returns the commodity for this transaction * @return Commodity of the transaction */ - public Commodity getCommodity() { + public @NonNull Commodity getCommodity() { return mCommodity; } @@ -366,9 +342,8 @@ public Commodity getCommodity() { * Sets the commodity for this transaction * @param commodity Commodity instance */ - public void setCommodity(Commodity commodity) { + public void setCommodity(@NonNull Commodity commodity) { this.mCommodity = commodity; - this.mCurrencyCode = commodity.getCurrencyCode(); } /** diff --git a/app/src/main/java/org/gnucash/android/receivers/TransactionAppWidgetProvider.java b/app/src/main/java/org/gnucash/android/receivers/TransactionAppWidgetProvider.java index 2f6e4d81c..92ae93543 100644 --- a/app/src/main/java/org/gnucash/android/receivers/TransactionAppWidgetProvider.java +++ b/app/src/main/java/org/gnucash/android/receivers/TransactionAppWidgetProvider.java @@ -18,11 +18,10 @@ import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; import android.content.Context; +import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; -import android.preference.PreferenceManager; import org.gnucash.android.db.adapter.BooksDbAdapter; -import org.gnucash.android.model.Book; import org.gnucash.android.ui.common.UxArgument; import org.gnucash.android.ui.homescreen.WidgetConfigurationActivity; import org.gnucash.android.ui.settings.PreferenceActivity; @@ -40,20 +39,9 @@ public class TransactionAppWidgetProvider extends AppWidgetProvider { public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); - final int N = appWidgetIds.length; - - // Perform this loop procedure for each App Widget that belongs to this provider - for (int i=0; i mBudgetAmountViews = new ArrayList<>(); private AccountsDbAdapter mAccountsDbAdapter; - @Bind(R.id.budget_amount_layout) LinearLayout mBudgetAmountTableLayout; - @Bind(R.id.calculator_keyboard) KeyboardView mKeyboardView; + @BindView(R.id.budget_amount_layout) LinearLayout mBudgetAmountTableLayout; + @BindView(R.id.calculator_keyboard) KeyboardView mKeyboardView; public static BudgetAmountEditorFragment newInstance(Bundle args){ BudgetAmountEditorFragment fragment = new BudgetAmountEditorFragment(); @@ -204,7 +204,7 @@ private void setupAccountSpinnerAdapter(){ if (mAccountCursor != null) { mAccountCursor.close(); } - mAccountCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(conditions, null); + mAccountCursor = mAccountsDbAdapter.fetchAccountsOrderedByFavoriteAndFullName(conditions, null); mAccountCursorAdapter = new QualifiedAccountNameCursorAdapter(getActivity(), mAccountCursor); } @@ -232,10 +232,10 @@ private List extractBudgetAmounts(){ * View holder for budget amounts */ class BudgetAmountViewHolder{ - @Bind(R.id.currency_symbol) TextView currencySymbolTextView; - @Bind(R.id.input_budget_amount) CalculatorEditText amountEditText; - @Bind(R.id.btn_remove_item) ImageView removeItemBtn; - @Bind(R.id.input_budget_account_spinner) Spinner budgetAccountSpinner; + @BindView(R.id.currency_symbol) TextView currencySymbolTextView; + @BindView(R.id.input_budget_amount) CalculatorEditText amountEditText; + @BindView(R.id.btn_remove_item) ImageView removeItemBtn; + @BindView(R.id.input_budget_account_spinner) Spinner budgetAccountSpinner; View itemView; public BudgetAmountViewHolder(View view){ diff --git a/app/src/main/java/org/gnucash/android/ui/budget/BudgetDetailFragment.java b/app/src/main/java/org/gnucash/android/ui/budget/BudgetDetailFragment.java index 730eb993d..8e8bbf7f9 100644 --- a/app/src/main/java/org/gnucash/android/ui/budget/BudgetDetailFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/budget/BudgetDetailFragment.java @@ -61,17 +61,17 @@ import java.util.ArrayList; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** * Fragment for displaying budget details */ public class BudgetDetailFragment extends Fragment implements Refreshable { - @Bind(R.id.primary_text) TextView mBudgetNameTextView; - @Bind(R.id.secondary_text) TextView mBudgetDescriptionTextView; - @Bind(R.id.budget_recurrence) TextView mBudgetRecurrence; - @Bind(R.id.budget_amount_recycler) EmptyRecyclerView mRecyclerView; + @BindView(R.id.primary_text) TextView mBudgetNameTextView; + @BindView(R.id.secondary_text) TextView mBudgetDescriptionTextView; + @BindView(R.id.budget_recurrence) TextView mBudgetRecurrence; + @BindView(R.id.budget_amount_recycler) EmptyRecyclerView mRecyclerView; private String mBudgetUID; private BudgetsDbAdapter mBudgetsDbAdapter; @@ -218,8 +218,8 @@ public void onBindViewHolder(BudgetAmountViewHolder holder, final int position) double budgetProgress = 0; if (projectedAmount.asDouble() != 0){ budgetProgress = spentAmount.asBigDecimal().divide(projectedAmount.asBigDecimal(), - spentAmount.getCurrency().getDefaultFractionDigits(), RoundingMode.HALF_EVEN) - .doubleValue(); + spentAmount.getCommodity().getSmallestFractionDigits(), + RoundingMode.HALF_EVEN).doubleValue(); } holder.budgetIndicator.setProgress((int) (budgetProgress * 100)); @@ -293,12 +293,12 @@ public int getItemCount() { } class BudgetAmountViewHolder extends RecyclerView.ViewHolder { - @Bind(R.id.budget_account) TextView budgetAccount; - @Bind(R.id.budget_amount) TextView budgetAmount; - @Bind(R.id.budget_spent) TextView budgetSpent; - @Bind(R.id.budget_left) TextView budgetLeft; - @Bind(R.id.budget_indicator) ProgressBar budgetIndicator; - @Bind(R.id.budget_chart) BarChart budgetChart; + @BindView(R.id.budget_account) TextView budgetAccount; + @BindView(R.id.budget_amount) TextView budgetAmount; + @BindView(R.id.budget_spent) TextView budgetSpent; + @BindView(R.id.budget_left) TextView budgetLeft; + @BindView(R.id.budget_indicator) ProgressBar budgetIndicator; + @BindView(R.id.budget_chart) BarChart budgetChart; public BudgetAmountViewHolder(View itemView) { super(itemView); diff --git a/app/src/main/java/org/gnucash/android/ui/budget/BudgetFormFragment.java b/app/src/main/java/org/gnucash/android/ui/budget/BudgetFormFragment.java index e727912f2..553a400c9 100644 --- a/app/src/main/java/org/gnucash/android/ui/budget/BudgetFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/budget/BudgetFormFragment.java @@ -70,7 +70,7 @@ import java.util.Date; import java.util.GregorianCalendar; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -80,16 +80,16 @@ public class BudgetFormFragment extends Fragment implements RecurrencePickerDialogFragment.OnRecurrenceSetListener, CalendarDatePickerDialogFragment.OnDateSetListener { public static final int REQUEST_EDIT_BUDGET_AMOUNTS = 0xBA; - @Bind(R.id.input_budget_name) EditText mBudgetNameInput; - @Bind(R.id.input_description) EditText mDescriptionInput; - @Bind(R.id.input_recurrence) TextView mRecurrenceInput; - @Bind(R.id.name_text_input_layout) TextInputLayout mNameTextInputLayout; - @Bind(R.id.calculator_keyboard) KeyboardView mKeyboardView; - @Bind(R.id.input_budget_amount) CalculatorEditText mBudgetAmountInput; - @Bind(R.id.input_budget_account_spinner) Spinner mBudgetAccountSpinner; - @Bind(R.id.btn_add_budget_amount) Button mAddBudgetAmount; - @Bind(R.id.input_start_date) TextView mStartDateInput; - @Bind(R.id.budget_amount_layout) View mBudgetAmountLayout; + @BindView(R.id.input_budget_name) EditText mBudgetNameInput; + @BindView(R.id.input_description) EditText mDescriptionInput; + @BindView(R.id.input_recurrence) TextView mRecurrenceInput; + @BindView(R.id.name_text_input_layout) TextInputLayout mNameTextInputLayout; + @BindView(R.id.calculator_keyboard) KeyboardView mKeyboardView; + @BindView(R.id.input_budget_amount) CalculatorEditText mBudgetAmountInput; + @BindView(R.id.input_budget_account_spinner) Spinner mBudgetAccountSpinner; + @BindView(R.id.btn_add_budget_amount) Button mAddBudgetAmount; + @BindView(R.id.input_start_date) TextView mStartDateInput; + @BindView(R.id.budget_amount_layout) View mBudgetAmountLayout; EventRecurrence mEventRecurrence = new EventRecurrence(); String mRecurrenceRule; @@ -122,7 +122,7 @@ public void onCreate(@Nullable Bundle savedInstanceState) { mBudgetAmounts = new ArrayList<>(); String conditions = "(" + DatabaseSchema.AccountEntry.COLUMN_HIDDEN + " = 0 )"; mAccountsDbAdapter = AccountsDbAdapter.getInstance(); - Cursor accountCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(conditions, null); + Cursor accountCursor = mAccountsDbAdapter.fetchAccountsOrderedByFavoriteAndFullName(conditions, null); mAccountsCursorAdapter = new QualifiedAccountNameCursorAdapter(getActivity(), accountCursor); } @@ -291,9 +291,9 @@ public void onClickBudgetStartDate(View v) { int year = calendar.get(Calendar.YEAR); int monthOfYear = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); - CalendarDatePickerDialogFragment datePickerDialog = CalendarDatePickerDialogFragment.newInstance( - BudgetFormFragment.this, - year, monthOfYear, dayOfMonth); + CalendarDatePickerDialogFragment datePickerDialog = new CalendarDatePickerDialogFragment(); + datePickerDialog.setOnDateSetListener(BudgetFormFragment.this); + datePickerDialog.setPreselectedDate(year, monthOfYear, dayOfMonth); datePickerDialog.show(getFragmentManager(), "date_picker_fragment"); } diff --git a/app/src/main/java/org/gnucash/android/ui/budget/BudgetListFragment.java b/app/src/main/java/org/gnucash/android/ui/budget/BudgetListFragment.java index cc784ea29..c0057508e 100644 --- a/app/src/main/java/org/gnucash/android/ui/budget/BudgetListFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/budget/BudgetListFragment.java @@ -51,6 +51,7 @@ import org.gnucash.android.db.adapter.BudgetsDbAdapter; import org.gnucash.android.model.Budget; import org.gnucash.android.model.BudgetAmount; +import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; import org.gnucash.android.ui.common.FormActivity; import org.gnucash.android.ui.common.Refreshable; @@ -60,9 +61,8 @@ import java.math.BigDecimal; import java.math.RoundingMode; -import java.util.Currency; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -79,8 +79,8 @@ public class BudgetListFragment extends Fragment implements Refreshable, private BudgetsDbAdapter mBudgetsDbAdapter; - @Bind(R.id.budget_recycler_view) EmptyRecyclerView mRecyclerView; - @Bind(R.id.empty_view) Button mProposeBudgets; + @BindView(R.id.budget_recycler_view) EmptyRecyclerView mRecyclerView; + @BindView(R.id.empty_view) Button mProposeBudgets; @Nullable @Override @@ -231,13 +231,13 @@ public void onBindViewHolderCursor(BudgetViewHolder holder, Cursor cursor) { } Money budgetTotal = budget.getAmountSum(); - Currency currency = budgetTotal.getCurrency(); - String usedAmount = currency.getSymbol() + spentAmountValue+ " of " + Commodity commodity = budgetTotal.getCommodity(); + String usedAmount = commodity.getSymbol() + spentAmountValue + " of " + budgetTotal.formattedString(); holder.budgetAmount.setText(usedAmount); double budgetProgress = spentAmountValue.divide(budgetTotal.asBigDecimal(), - currency.getDefaultFractionDigits(), RoundingMode.HALF_EVEN) + commodity.getSmallestFractionDigits(), RoundingMode.HALF_EVEN) .doubleValue(); holder.budgetIndicator.setProgress((int) (budgetProgress * 100)); @@ -260,12 +260,12 @@ public BudgetViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { } class BudgetViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener{ - @Bind(R.id.primary_text) TextView budgetName; - @Bind(R.id.secondary_text) TextView accountName; - @Bind(R.id.budget_amount) TextView budgetAmount; - @Bind(R.id.options_menu) ImageView optionsMenu; - @Bind(R.id.budget_indicator) ProgressBar budgetIndicator; - @Bind(R.id.budget_recurrence) TextView budgetRecurrence; + @BindView(R.id.primary_text) TextView budgetName; + @BindView(R.id.secondary_text) TextView accountName; + @BindView(R.id.budget_amount) TextView budgetAmount; + @BindView(R.id.options_menu) ImageView optionsMenu; + @BindView(R.id.budget_indicator) ProgressBar budgetIndicator; + @BindView(R.id.budget_recurrence) TextView budgetRecurrence; long budgetId; public BudgetViewHolder(View itemView) { diff --git a/app/src/main/java/org/gnucash/android/ui/common/BaseDrawerActivity.java b/app/src/main/java/org/gnucash/android/ui/common/BaseDrawerActivity.java index 89fa315a0..4a5b7eb36 100644 --- a/app/src/main/java/org/gnucash/android/ui/common/BaseDrawerActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/common/BaseDrawerActivity.java @@ -51,7 +51,7 @@ import org.gnucash.android.ui.settings.PreferenceActivity; import org.gnucash.android.ui.transaction.ScheduledActionsActivity; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; @@ -77,10 +77,10 @@ public abstract class BaseDrawerActivity extends PasscodeLockActivity implements PopupMenu.OnMenuItemClickListener { public static final int ID_MANAGE_BOOKS = 0xB00C; - @Bind(R.id.drawer_layout) DrawerLayout mDrawerLayout; - @Bind(R.id.nav_view) NavigationView mNavigationView; - @Bind(R.id.toolbar) Toolbar mToolbar; - @Bind(R.id.toolbar_progress) ProgressBar mToolbarProgress; + @BindView(R.id.drawer_layout) DrawerLayout mDrawerLayout; + @BindView(R.id.nav_view) NavigationView mNavigationView; + @BindView(R.id.toolbar) Toolbar mToolbar; + @BindView(R.id.toolbar_progress) ProgressBar mToolbarProgress; protected TextView mBookNameTextView; protected ActionBarDrawerToggle mDrawerToggle; diff --git a/app/src/main/java/org/gnucash/android/ui/common/UxArgument.java b/app/src/main/java/org/gnucash/android/ui/common/UxArgument.java index 9a4a07333..03814b170 100644 --- a/app/src/main/java/org/gnucash/android/ui/common/UxArgument.java +++ b/app/src/main/java/org/gnucash/android/ui/common/UxArgument.java @@ -72,6 +72,11 @@ public final class UxArgument { */ public static final String SELECTED_ACCOUNT_UID = "account_uid"; + /** + * Key for passing whether a widget should hide the account balance or not + */ + public static final String HIDE_ACCOUNT_BALANCE_IN_WIDGET = "hide_account_balance"; + /** * Key for passing argument for the parent account GUID. */ diff --git a/app/src/main/java/org/gnucash/android/ui/export/ExportFormFragment.java b/app/src/main/java/org/gnucash/android/ui/export/ExportFormFragment.java index a5b8ee1cd..7ebcb6954 100644 --- a/app/src/main/java/org/gnucash/android/ui/export/ExportFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/export/ExportFormFragment.java @@ -49,12 +49,13 @@ import com.codetroopers.betterpickers.recurrencepicker.EventRecurrence; import com.codetroopers.betterpickers.recurrencepicker.EventRecurrenceFormatter; import com.codetroopers.betterpickers.recurrencepicker.RecurrencePickerDialogFragment; -import com.dropbox.sync.android.DbxAccountManager; +import com.dropbox.core.android.Auth; import org.gnucash.android.R; import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.db.adapter.DatabaseAdapter; import org.gnucash.android.db.adapter.ScheduledActionDbAdapter; +import org.gnucash.android.export.DropboxHelper; import org.gnucash.android.export.ExportAsyncTask; import org.gnucash.android.export.ExportFormat; import org.gnucash.android.export.ExportParams; @@ -76,7 +77,7 @@ import java.util.Date; import java.util.GregorianCalendar; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; @@ -96,40 +97,40 @@ public class ExportFormFragment extends Fragment implements * The destination could either be SD card, or another application which * accepts files, like Google Drive. */ - @Bind(R.id.spinner_export_destination) Spinner mDestinationSpinner; + @BindView(R.id.spinner_export_destination) Spinner mDestinationSpinner; /** * Checkbox for deleting all transactions after exporting them */ - @Bind(R.id.checkbox_post_export_delete) CheckBox mDeleteAllCheckBox; + @BindView(R.id.checkbox_post_export_delete) CheckBox mDeleteAllCheckBox; /** * Text view for showing warnings based on chosen export format */ - @Bind(R.id.export_warning) TextView mExportWarningTextView; + @BindView(R.id.export_warning) TextView mExportWarningTextView; /** * Recurrence text view */ - @Bind(R.id.input_recurrence) TextView mRecurrenceTextView; + @BindView(R.id.input_recurrence) TextView mRecurrenceTextView; /** * Text view displaying start date to export from */ - @Bind(R.id.export_start_date) TextView mExportStartDate; + @BindView(R.id.export_start_date) TextView mExportStartDate; - @Bind(R.id.export_start_time) TextView mExportStartTime; + @BindView(R.id.export_start_time) TextView mExportStartTime; /** * Switch toggling whether to export all transactions or not */ - @Bind(R.id.switch_export_all) SwitchCompat mExportAllSwitch; + @BindView(R.id.switch_export_all) SwitchCompat mExportAllSwitch; - @Bind(R.id.export_date_layout) LinearLayout mExportDateLayout; + @BindView(R.id.export_date_layout) LinearLayout mExportDateLayout; - @Bind(R.id.radio_ofx_format) RadioButton mOfxRadioButton; - @Bind(R.id.radio_qif_format) RadioButton mQifRadioButton; - @Bind(R.id.radio_xml_format) RadioButton mXmlRadioButton; + @BindView(R.id.radio_ofx_format) RadioButton mOfxRadioButton; + @BindView(R.id.radio_qif_format) RadioButton mQifRadioButton; + @BindView(R.id.radio_xml_format) RadioButton mXmlRadioButton; /** * Event recurrence options @@ -235,7 +236,13 @@ public void onActivityCreated(Bundle savedInstanceState) { getSDWritePermission(); } - @Override + @Override + public void onResume() { + super.onResume(); + DropboxHelper.retrieveAndSaveToken(); + } + + @Override public void onPause() { super.onPause(); // When the user try to export sharing to 3rd party service like DropBox @@ -317,10 +324,9 @@ public void onItemSelected(AdapterView parent, View view, int position, long mExportTarget = ExportParams.ExportTarget.DROPBOX; String dropboxAppKey = getString(R.string.dropbox_app_key, BackupPreferenceFragment.DROPBOX_APP_KEY); String dropboxAppSecret = getString(R.string.dropbox_app_secret, BackupPreferenceFragment.DROPBOX_APP_SECRET); - DbxAccountManager mDbxAccountManager = DbxAccountManager.getInstance(getActivity().getApplicationContext(), - dropboxAppKey, dropboxAppSecret); - if (!mDbxAccountManager.hasLinkedAccount()) { - mDbxAccountManager.startLink(getActivity(), 0); + + if (!DropboxHelper.hasToken()) { + Auth.startOAuth2Authentication(getActivity(), dropboxAppKey); } break; case 2: @@ -363,7 +369,7 @@ public void onNothingSelected(AdapterView parent) { Timestamp timestamp = PreferencesHelper.getLastExportTime(); mExportStartCalendar.setTimeInMillis(timestamp.getTime()); - Date date = new Date(timestamp.getTime()); + final Date date = new Date(timestamp.getTime()); mExportStartDate.setText(TransactionFormFragment.DATE_FORMATTER.format(date)); mExportStartTime.setText(TransactionFormFragment.TIME_FORMATTER.format(date)); @@ -384,9 +390,9 @@ public void onClick(View v) { int year = calendar.get(Calendar.YEAR); int monthOfYear = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); - CalendarDatePickerDialogFragment datePickerDialog = CalendarDatePickerDialogFragment.newInstance( - ExportFormFragment.this, - year, monthOfYear, dayOfMonth); + CalendarDatePickerDialogFragment datePickerDialog = new CalendarDatePickerDialogFragment(); + datePickerDialog.setOnDateSetListener(ExportFormFragment.this); + datePickerDialog.setPreselectedDate(year, monthOfYear, dayOfMonth); datePickerDialog.show(getFragmentManager(), "date_picker_fragment"); } }); @@ -406,9 +412,10 @@ public void onClick(View v) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timeMillis); - RadialTimePickerDialogFragment timePickerDialog = RadialTimePickerDialogFragment.newInstance( - ExportFormFragment.this, calendar.get(Calendar.HOUR_OF_DAY), - calendar.get(Calendar.MINUTE), true); + RadialTimePickerDialogFragment timePickerDialog = new RadialTimePickerDialogFragment(); + timePickerDialog.setOnTimeSetListener(ExportFormFragment.this); + timePickerDialog.setStartTime(calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE)); timePickerDialog.show(getFragmentManager(), "time_picker_dialog_fragment"); } }); diff --git a/app/src/main/java/org/gnucash/android/ui/homescreen/WidgetConfigurationActivity.java b/app/src/main/java/org/gnucash/android/ui/homescreen/WidgetConfigurationActivity.java index 76e301587..0fbaba8fd 100644 --- a/app/src/main/java/org/gnucash/android/ui/homescreen/WidgetConfigurationActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/homescreen/WidgetConfigurationActivity.java @@ -28,10 +28,13 @@ import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.support.v4.widget.SimpleCursorAdapter; +import android.support.v7.preference.PreferenceManager; import android.util.Log; import android.view.View; import android.widget.AdapterView; import android.widget.Button; +import android.widget.CheckBox; +import android.widget.ImageButton; import android.widget.RemoteViews; import android.widget.Spinner; import android.widget.Toast; @@ -54,8 +57,9 @@ import org.gnucash.android.util.QualifiedAccountNameCursorAdapter; import java.util.Locale; +import java.util.prefs.Preferences; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -67,11 +71,13 @@ public class WidgetConfigurationActivity extends Activity { private AccountsDbAdapter mAccountsDbAdapter; private int mAppWidgetId; - @Bind(R.id.input_accounts_spinner) Spinner mAccountsSpinner; - @Bind(R.id.input_books_spinner) Spinner mBooksSpinner; + @BindView(R.id.input_accounts_spinner) Spinner mAccountsSpinner; + @BindView(R.id.input_books_spinner) Spinner mBooksSpinner; + @BindView(R.id.input_hide_account_balance) CheckBox mHideAccountBalance; + @BindView(R.id.btn_save) Button mOkButton; + @BindView(R.id.btn_cancel) Button mCancelButton; + - @Bind(R.id.btn_save) Button mOkButton; - @Bind(R.id.btn_cancel) Button mCancelButton; private SimpleCursorAdapter mAccountsCursorAdapter; @@ -116,7 +122,11 @@ public void onCreate(Bundle savedInstanceState) { //without this line, the app crashes when a user tries to select an account mAccountsCursorAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); mAccountsSpinner.setAdapter(mAccountsCursorAdapter); - + + boolean passcodeEnabled = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()) + .getBoolean(UxArgument.ENABLED_PASSCODE, false); + mHideAccountBalance.setChecked(passcodeEnabled); + bindListeners(); } @@ -157,21 +167,14 @@ public void onClick(View v) { if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID){ finish(); return; - } - - long accountId = mAccountsSpinner.getSelectedItemId(); - String accountUID = mAccountsDbAdapter.getUID(accountId); - - long bookId = mBooksSpinner.getSelectedItemId(); - String bookUID = BooksDbAdapter.getInstance().getUID(bookId); + } - SharedPreferences prefs = PreferenceActivity.getBookSharedPreferences(bookUID); - //PreferenceManager.getDefaultSharedPreferences(WidgetConfigurationActivity.this); - Editor editor = prefs.edit(); - editor.putString(UxArgument.SELECTED_ACCOUNT_UID + mAppWidgetId, accountUID); - editor.apply(); + String bookUID = BooksDbAdapter.getInstance().getUID(mBooksSpinner.getSelectedItemId()); + String accountUID = mAccountsDbAdapter.getUID(mAccountsSpinner.getSelectedItemId()); + boolean hideAccountBalance = mHideAccountBalance.isChecked(); - updateWidget(WidgetConfigurationActivity.this, mAppWidgetId, accountUID, bookUID); + configureWidget(WidgetConfigurationActivity.this, mAppWidgetId, bookUID, accountUID, hideAccountBalance); + updateWidget(WidgetConfigurationActivity.this, mAppWidgetId); Intent resultValue = new Intent(); resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId); @@ -189,18 +192,76 @@ public void onClick(View v) { }); } + /** + * Configure a given widget with the given parameters. + * @param context The current context + * @param appWidgetId ID of the widget to configure + * @param bookUID UID of the book for this widget + * @param accountUID UID of the account for this widget + * @param hideAccountBalance true if the account balance should be hidden, + * false otherwise + */ + public static void configureWidget(final Context context, int appWidgetId, String bookUID, String accountUID, boolean hideAccountBalance) { + context.getSharedPreferences("widget:" + appWidgetId, MODE_PRIVATE).edit() + .putString(UxArgument.BOOK_UID, bookUID) + .putString(UxArgument.SELECTED_ACCOUNT_UID, accountUID) + .putBoolean(UxArgument.HIDE_ACCOUNT_BALANCE_IN_WIDGET, hideAccountBalance) + .apply(); + } + + /** + * Remove the configuration for a widget. Primarily this should be called when a widget is + * destroyed. + * @param context The current context + * @param appWidgetId ID of the widget whose configuration should be removed + */ + public static void removeWidgetConfiguration(final Context context, int appWidgetId) { + context.getSharedPreferences("widget:" + appWidgetId, MODE_PRIVATE).edit() + .clear() + .apply(); + } + + /** + * Load obsolete preferences for a widget, if they exist, and save them using the new widget + * configuration format. + * @param context The current context + * @param appWidgetId ID of the widget whose configuration to load/save + */ + private static void loadOldPreferences(Context context, int appWidgetId) { + SharedPreferences preferences = PreferenceActivity.getActiveBookSharedPreferences(); + String accountUID = preferences.getString(UxArgument.SELECTED_ACCOUNT_UID + appWidgetId, null); + if (accountUID != null) { + String bookUID = BooksDbAdapter.getInstance().getActiveBookUID(); + boolean hideAccountBalance = preferences.getBoolean(UxArgument.HIDE_ACCOUNT_BALANCE_IN_WIDGET + appWidgetId, false); + configureWidget(context, appWidgetId, bookUID, accountUID, hideAccountBalance); + preferences.edit() + .remove(UxArgument.SELECTED_ACCOUNT_UID + appWidgetId) + .remove(UxArgument.HIDE_ACCOUNT_BALANCE_IN_WIDGET + appWidgetId) + .apply(); + } + } + /** * Updates the widget with id appWidgetId with information from the * account with record ID accountId * If the account has been deleted, then a notice is posted in the widget * @param appWidgetId ID of the widget to be updated - * @param accountUID GUID of the account tied to the widget - * @param bookUID GUID of the book with the relevant account */ - public static void updateWidget(final Context context, int appWidgetId, String accountUID, String bookUID) { + public static void updateWidget(final Context context, int appWidgetId) { Log.i("WidgetConfiguration", "Updating widget: " + appWidgetId); AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); + loadOldPreferences(context, appWidgetId); + + SharedPreferences preferences = context.getSharedPreferences("widget:" + appWidgetId, MODE_PRIVATE); + String bookUID = preferences.getString(UxArgument.BOOK_UID, null); + String accountUID = preferences.getString(UxArgument.SELECTED_ACCOUNT_UID, null); + boolean hideAccountBalance = preferences.getBoolean(UxArgument.HIDE_ACCOUNT_BALANCE_IN_WIDGET, false); + + if (bookUID == null || accountUID == null) { + return; + } + AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(BookDbHelper.getDatabase(bookUID)); final Account account; @@ -231,10 +292,14 @@ public static void updateWidget(final Context context, int appWidgetId, String a Money accountBalance = accountsDbAdapter.getAccountBalance(accountUID, -1, System.currentTimeMillis()); - views.setTextViewText(R.id.transactions_summary, - accountBalance.formattedString(Locale.getDefault())); - int color = accountBalance.isNegative() ? R.color.debit_red : R.color.credit_green; - views.setTextColor(R.id.transactions_summary, context.getResources().getColor(color)); + if (hideAccountBalance) { + views.setViewVisibility(R.id.transactions_summary, View.GONE); + } else { + views.setTextViewText(R.id.transactions_summary, + accountBalance.formattedString(Locale.getDefault())); + int color = accountBalance.isNegative() ? R.color.debit_red : R.color.credit_green; + views.setTextColor(R.id.transactions_summary, context.getResources().getColor(color)); + } Intent accountViewIntent = new Intent(context, TransactionsActivity.class); @@ -246,19 +311,25 @@ public static void updateWidget(final Context context, int appWidgetId, String a .getActivity(context, appWidgetId, accountViewIntent, 0); views.setOnClickPendingIntent(R.id.widget_layout, accountPendingIntent); - Intent newTransactionIntent = new Intent(context, FormActivity.class); - newTransactionIntent.setAction(Intent.ACTION_INSERT_OR_EDIT); - newTransactionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - newTransactionIntent.putExtra(UxArgument.FORM_TYPE, FormActivity.FormType.TRANSACTION.name()); - newTransactionIntent.putExtra(UxArgument.BOOK_UID, bookUID); - newTransactionIntent.putExtra(UxArgument.SELECTED_ACCOUNT_UID, accountUID); - PendingIntent pendingIntent = PendingIntent - .getActivity(context, appWidgetId, newTransactionIntent, 0); - views.setOnClickPendingIntent(R.id.btn_new_transaction, pendingIntent); + if (accountsDbAdapter.isPlaceholderAccount(accountUID)) { + views.setOnClickPendingIntent(R.id.btn_view_account, accountPendingIntent); + views.setViewVisibility(R.id.btn_new_transaction, View.GONE); + } else { + Intent newTransactionIntent = new Intent(context, FormActivity.class); + newTransactionIntent.setAction(Intent.ACTION_INSERT_OR_EDIT); + newTransactionIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + newTransactionIntent.putExtra(UxArgument.FORM_TYPE, FormActivity.FormType.TRANSACTION.name()); + newTransactionIntent.putExtra(UxArgument.BOOK_UID, bookUID); + newTransactionIntent.putExtra(UxArgument.SELECTED_ACCOUNT_UID, accountUID); + PendingIntent pendingIntent = PendingIntent + .getActivity(context, appWidgetId, newTransactionIntent, 0); + views.setOnClickPendingIntent(R.id.btn_new_transaction, pendingIntent); + views.setViewVisibility(R.id.btn_view_account, View.GONE); + } appWidgetManager.updateAppWidget(appWidgetId, views); } - + /** * Updates all widgets belonging to the application * @param context Application context @@ -272,19 +343,10 @@ public static void updateAllWidgets(final Context context){ //update widgets asynchronously so as not to block method which called the update //inside the computation of the account balance new Thread(new Runnable() { - SharedPreferences defaultSharedPrefs = PreferenceActivity.getActiveBookSharedPreferences(); - //PreferenceManager.getDefaultSharedPreferences(context); - @Override public void run() { for (final int widgetId : appWidgetIds) { - final String accountUID = defaultSharedPrefs - .getString(UxArgument.SELECTED_ACCOUNT_UID + widgetId, null); - - if (accountUID == null) - continue; - - updateWidget(context, widgetId, accountUID, BooksDbAdapter.getInstance().getActiveBookUID()); + updateWidget(context, widgetId); } } }).start(); diff --git a/app/src/main/java/org/gnucash/android/ui/report/BaseReportFragment.java b/app/src/main/java/org/gnucash/android/ui/report/BaseReportFragment.java index e6f849e40..28fbfa1aa 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/BaseReportFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/BaseReportFragment.java @@ -46,7 +46,7 @@ import org.joda.time.Months; import org.joda.time.Years; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -103,7 +103,7 @@ public abstract class BaseReportFragment extends Fragment implements protected ReportsActivity mReportsActivity; - @Nullable @Bind(R.id.selected_chart_slice) protected TextView mSelectedValueTextView; + @Nullable @BindView(R.id.selected_chart_slice) protected TextView mSelectedValueTextView; private AsyncTask mReportGenerator; diff --git a/app/src/main/java/org/gnucash/android/ui/report/ReportsActivity.java b/app/src/main/java/org/gnucash/android/ui/report/ReportsActivity.java index 5f8b47e9b..7ce7bf2dc 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/ReportsActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/report/ReportsActivity.java @@ -45,12 +45,11 @@ import org.gnucash.android.ui.util.dialog.DateRangePickerDialogFragment; import org.joda.time.LocalDate; -import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; /** * Activity for displaying report fragments (which must implement {@link BaseReportFragment}) @@ -76,9 +75,9 @@ public class ReportsActivity extends BaseDrawerActivity implements AdapterView.O }; private static final String STATE_REPORT_TYPE = "STATE_REPORT_TYPE"; - @Bind(R.id.time_range_spinner) Spinner mTimeRangeSpinner; - @Bind(R.id.report_account_type_spinner) Spinner mAccountTypeSpinner; - @Bind(R.id.toolbar_spinner) Spinner mReportTypeSpinner; + @BindView(R.id.time_range_spinner) Spinner mTimeRangeSpinner; + @BindView(R.id.report_account_type_spinner) Spinner mAccountTypeSpinner; + @BindView(R.id.toolbar_spinner) Spinner mReportTypeSpinner; private TransactionsDbAdapter mTransactionsDbAdapter; private AccountType mAccountType = AccountType.EXPENSE; diff --git a/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java b/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java index f0139f677..0f247f182 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java @@ -50,7 +50,7 @@ import java.util.Collections; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.OnClick; import static com.github.mikephil.charting.components.Legend.LegendPosition; @@ -63,15 +63,15 @@ public class ReportsOverviewFragment extends BaseReportFragment { public static final int LEGEND_TEXT_SIZE = 14; - @Bind(R.id.btn_pie_chart) Button mPieChartButton; - @Bind(R.id.btn_bar_chart) Button mBarChartButton; - @Bind(R.id.btn_line_chart) Button mLineChartButton; - @Bind(R.id.btn_balance_sheet) Button mBalanceSheetButton; + @BindView(R.id.btn_pie_chart) Button mPieChartButton; + @BindView(R.id.btn_bar_chart) Button mBarChartButton; + @BindView(R.id.btn_line_chart) Button mLineChartButton; + @BindView(R.id.btn_balance_sheet) Button mBalanceSheetButton; - @Bind(R.id.pie_chart) PieChart mChart; - @Bind(R.id.total_assets) TextView mTotalAssets; - @Bind(R.id.total_liabilities) TextView mTotalLiabilities; - @Bind(R.id.net_worth) TextView mNetWorth; + @BindView(R.id.pie_chart) PieChart mChart; + @BindView(R.id.total_assets) TextView mTotalAssets; + @BindView(R.id.total_liabilities) TextView mTotalLiabilities; + @BindView(R.id.net_worth) TextView mNetWorth; private AccountsDbAdapter mAccountsDbAdapter; private Money mAssetsBalance; diff --git a/app/src/main/java/org/gnucash/android/ui/report/barchart/StackedBarChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/barchart/StackedBarChartFragment.java index 7408fb738..5556c7896 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/barchart/StackedBarChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/barchart/StackedBarChartFragment.java @@ -52,7 +52,7 @@ import java.util.List; import java.util.Map; -import butterknife.Bind; +import butterknife.BindView; import static org.gnucash.android.ui.report.ReportsActivity.COLORS; @@ -73,7 +73,7 @@ public class StackedBarChartFragment extends BaseReportFragment { private AccountsDbAdapter mAccountsDbAdapter = AccountsDbAdapter.getInstance(); - @Bind(R.id.bar_chart) BarChart mChart; + @BindView(R.id.bar_chart) BarChart mChart; private boolean mUseAccountColor = true; private boolean mTotalPercentageMode = true; diff --git a/app/src/main/java/org/gnucash/android/ui/report/linechart/CashFlowLineChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/linechart/CashFlowLineChartFragment.java index 40e7b18dc..2089ae461 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/linechart/CashFlowLineChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/linechart/CashFlowLineChartFragment.java @@ -51,7 +51,7 @@ import java.util.List; import java.util.Map; -import butterknife.Bind; +import butterknife.BindView; /** * Fragment for line chart reports @@ -80,7 +80,7 @@ public class CashFlowLineChartFragment extends BaseReportFragment { private long mLatestTransactionTimestamp; private boolean mChartDataPresent = true; - @Bind(R.id.line_chart) LineChart mChart; + @BindView(R.id.line_chart) LineChart mChart; @Override public int getLayoutResource() { diff --git a/app/src/main/java/org/gnucash/android/ui/report/piechart/PieChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/piechart/PieChartFragment.java index fab2e24be..eef9fd9ce 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/piechart/PieChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/piechart/PieChartFragment.java @@ -42,7 +42,7 @@ import java.util.Collections; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import static com.github.mikephil.charting.components.Legend.LegendForm; import static com.github.mikephil.charting.components.Legend.LegendPosition; @@ -67,7 +67,7 @@ public class PieChartFragment extends BaseReportFragment { */ private static final double GROUPING_SMALLER_SLICES_THRESHOLD = 5; - @Bind(R.id.pie_chart) PieChart mChart; + @BindView(R.id.pie_chart) PieChart mChart; private AccountsDbAdapter mAccountsDbAdapter; diff --git a/app/src/main/java/org/gnucash/android/ui/report/sheet/BalanceSheetFragment.java b/app/src/main/java/org/gnucash/android/ui/report/sheet/BalanceSheetFragment.java index ad459e301..4ca91569d 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/sheet/BalanceSheetFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/sheet/BalanceSheetFragment.java @@ -38,7 +38,7 @@ import java.util.ArrayList; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; /** * Balance sheet report fragment @@ -46,11 +46,11 @@ */ public class BalanceSheetFragment extends BaseReportFragment { - @Bind(R.id.table_assets) TableLayout mAssetsTableLayout; - @Bind(R.id.table_liabilities) TableLayout mLiabilitiesTableLayout; - @Bind(R.id.table_equity) TableLayout mEquityTableLayout; + @BindView(R.id.table_assets) TableLayout mAssetsTableLayout; + @BindView(R.id.table_liabilities) TableLayout mLiabilitiesTableLayout; + @BindView(R.id.table_equity) TableLayout mEquityTableLayout; - @Bind(R.id.total_liability_and_equity) TextView mNetWorth; + @BindView(R.id.total_liability_and_equity) TextView mNetWorth; AccountsDbAdapter mAccountsDbAdapter = AccountsDbAdapter.getInstance(); diff --git a/app/src/main/java/org/gnucash/android/ui/settings/BackupPreferenceFragment.java b/app/src/main/java/org/gnucash/android/ui/settings/BackupPreferenceFragment.java index b262a1578..e0d618794 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/BackupPreferenceFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/BackupPreferenceFragment.java @@ -35,7 +35,7 @@ import android.widget.ArrayAdapter; import android.widget.Toast; -import com.dropbox.sync.android.DbxAccountManager; +import com.dropbox.core.android.Auth; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GooglePlayServicesUtil; import com.google.android.gms.common.api.GoogleApiClient; @@ -84,9 +84,12 @@ public class BackupPreferenceFragment extends PreferenceFragmentCompat implement * Testing app secret for DropBox API */ final static public String DROPBOX_APP_SECRET = "h2t9fphj3nr4wkw"; + + /** + * String for tagging log statements + */ public static final String LOG_TAG = "BackupPrefFragment"; - private DbxAccountManager mDbxAccountManager; /** * Client for Google Drive Sync */ @@ -107,11 +110,6 @@ public void onCreate(Bundle savedInstanceState) { actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setTitle(R.string.title_backup_prefs); - String dropboxAppKey = getString(R.string.dropbox_app_key, DROPBOX_APP_KEY); - String dropboxAppSecret = getString(R.string.dropbox_app_secret, DROPBOX_APP_SECRET); - mDbxAccountManager = DbxAccountManager.getInstance(getActivity().getApplicationContext(), - dropboxAppKey, dropboxAppSecret); - mGoogleApiClient = getGoogleApiClient(getActivity()); } @@ -119,11 +117,13 @@ public void onCreate(Bundle savedInstanceState) { @Override public void onResume() { super.onResume(); - SharedPreferences manager = PreferenceManager.getDefaultSharedPreferences(getActivity()); - + SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + + //if we are returning from DropBox authentication, save the key which was generated + String keyDefaultEmail = getString(R.string.key_default_export_email); Preference pref = findPreference(keyDefaultEmail); - String defaultEmail = manager.getString(keyDefaultEmail, null); + String defaultEmail = sharedPrefs.getString(keyDefaultEmail, null); if (defaultEmail != null && !defaultEmail.trim().isEmpty()){ pref.setSummary(defaultEmail); } @@ -131,7 +131,7 @@ public void onResume() { String keyDefaultExportFormat = getString(R.string.key_default_export_format); pref = findPreference(keyDefaultExportFormat); - String defaultExportFormat = manager.getString(keyDefaultExportFormat, null); + String defaultExportFormat = sharedPrefs.getString(keyDefaultExportFormat, null); if (defaultExportFormat != null && !defaultExportFormat.trim().isEmpty()){ pref.setSummary(defaultExportFormat); } @@ -225,7 +225,9 @@ public boolean onPreferenceChange(Preference preference, Object newValue) { * @param pref DropBox Sync preference */ public void toggleDropboxPreference(Preference pref) { - ((CheckBoxPreference)pref).setChecked(mDbxAccountManager.hasLinkedAccount()); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + String accessToken = prefs.getString(getString(R.string.key_dropbox_access_token), null); + ((CheckBoxPreference)pref).setChecked(accessToken != null); } /** @@ -253,10 +255,12 @@ public void toggleGoogleDrivePreference(Preference pref){ * If a link exists, it is removed else DropBox authorization is started */ private void toggleDropboxSync() { - if (mDbxAccountManager.hasLinkedAccount()){ - mDbxAccountManager.unlink(); + SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); + String accessToken = prefs.getString(getString(R.string.key_dropbox_access_token), null); + if (accessToken == null){ + Auth.startOAuth2Authentication(getActivity(), getString(R.string.dropbox_app_key)); } else { - mDbxAccountManager.startLink(getActivity(), REQUEST_LINK_TO_DBX); + prefs.edit().remove(getString(R.string.key_dropbox_access_token)).apply(); } } diff --git a/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java b/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java index 718b8602c..50df8e163 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/BookManagerFragment.java @@ -24,6 +24,7 @@ import android.support.annotation.Nullable; import android.support.v4.app.ListFragment; import android.support.v4.app.LoaderManager; +import android.support.v4.content.ContextCompat; import android.support.v4.content.Loader; import android.support.v4.widget.SimpleCursorAdapter; import android.support.v7.app.ActionBar; @@ -62,9 +63,9 @@ public class BookManagerFragment extends ListFragment implements LoaderManager.LoaderCallbacks, Refreshable{ - private static String LOG_TAG = "BookManagerFragment"; + private static final String LOG_TAG = "BookManagerFragment"; - SimpleCursorAdapter mCursorAdapter; + private SimpleCursorAdapter mCursorAdapter; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @@ -151,7 +152,7 @@ public void onLoaderReset(Loader loader) { private class BooksCursorAdapter extends SimpleCursorAdapter { - public BooksCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { + BooksCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to) { super(context, layout, c, from, to, 0); } @@ -216,9 +217,7 @@ public void onClick(DialogInterface dialog, int which) { AlertDialog dialog = dialogBuilder.create(); dialog.show(); //must be called before you can access buttons dialog.getButton(AlertDialog.BUTTON_POSITIVE) - .setTextColor(getResources().getColor(R.color.account_red)); - - + .setTextColor(ContextCompat.getColor(context, R.color.account_red)); } }); } @@ -267,7 +266,7 @@ private void setStatisticsText(View view, String bookUID) { * @author Ngewi Fet */ private static class BooksCursorLoader extends DatabaseCursorLoader { - public BooksCursorLoader(Context context){ + BooksCursorLoader(Context context){ super(context); } diff --git a/app/src/main/java/org/gnucash/android/ui/settings/PreferenceActivity.java b/app/src/main/java/org/gnucash/android/ui/settings/PreferenceActivity.java index f5c87a9c9..bb16e00b1 100644 --- a/app/src/main/java/org/gnucash/android/ui/settings/PreferenceActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/settings/PreferenceActivity.java @@ -36,10 +36,9 @@ import org.gnucash.android.R; import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.db.adapter.BooksDbAdapter; -import org.gnucash.android.model.Book; import org.gnucash.android.ui.passcode.PasscodeLockActivity; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -50,7 +49,7 @@ public class PreferenceActivity extends PasscodeLockActivity implements public static final String ACTION_MANAGE_BOOKS = "org.gnucash.android.intent.action.MANAGE_BOOKS"; - @Bind(R.id.slidingpane_layout) SlidingPaneLayout mSlidingPaneLayout; + @BindView(R.id.slidingpane_layout) SlidingPaneLayout mSlidingPaneLayout; @Override protected void onCreate(@Nullable Bundle savedInstanceState) { diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/SplitEditorFragment.java b/app/src/main/java/org/gnucash/android/ui/transaction/SplitEditorFragment.java index 8339c6bfc..3520cb8a9 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/SplitEditorFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/SplitEditorFragment.java @@ -69,7 +69,7 @@ import java.util.ArrayList; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -79,9 +79,9 @@ */ public class SplitEditorFragment extends Fragment { - @Bind(R.id.split_list_layout) LinearLayout mSplitsLinearLayout; - @Bind(R.id.calculator_keyboard) KeyboardView mKeyboardView; - @Bind(R.id.imbalance_textview) TextView mImbalanceTextView; + @BindView(R.id.split_list_layout) LinearLayout mSplitsLinearLayout; + @BindView(R.id.calculator_keyboard) KeyboardView mKeyboardView; + @BindView(R.id.imbalance_textview) TextView mImbalanceTextView; private AccountsDbAdapter mAccountsDbAdapter; private Cursor mCursor; @@ -228,13 +228,13 @@ private void initArgs() { * Holds a split item view and binds the items in it */ class SplitViewHolder implements OnTransferFundsListener{ - @Bind(R.id.input_split_memo) EditText splitMemoEditText; - @Bind(R.id.input_split_amount) CalculatorEditText splitAmountEditText; - @Bind(R.id.btn_remove_split) ImageView removeSplitButton; - @Bind(R.id.input_accounts_spinner) Spinner accountsSpinner; - @Bind(R.id.split_currency_symbol) TextView splitCurrencyTextView; - @Bind(R.id.split_uid) TextView splitUidTextView; - @Bind(R.id.btn_split_type) TransactionTypeSwitch splitTypeSwitch; + @BindView(R.id.input_split_memo) EditText splitMemoEditText; + @BindView(R.id.input_split_amount) CalculatorEditText splitAmountEditText; + @BindView(R.id.btn_remove_split) ImageView removeSplitButton; + @BindView(R.id.input_accounts_spinner) Spinner accountsSpinner; + @BindView(R.id.split_currency_symbol) TextView splitCurrencyTextView; + @BindView(R.id.split_uid) TextView splitUidTextView; + @BindView(R.id.btn_split_type) TransactionTypeSwitch splitTypeSwitch; View splitView; Money quantity; @@ -274,7 +274,7 @@ public void onClick(View view) { if (split != null) { splitAmountEditText.setCommodity(split.getValue().getCommodity()); splitAmountEditText.setValue(split.getFormattedValue().asBigDecimal()); - splitCurrencyTextView.setText(split.getValue().getCurrency().getSymbol()); + splitCurrencyTextView.setText(split.getValue().getCommodity().getSymbol()); splitMemoEditText.setText(split.getMemo()); splitUidTextView.setText(split.getUID()); String splitAccountUID = split.getAccountUID(); diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java index 2d90c3c44..30afa6d2a 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java @@ -30,7 +30,7 @@ import java.util.Date; import java.util.MissingFormatArgumentException; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -40,16 +40,16 @@ */ public class TransactionDetailActivity extends PasscodeLockActivity { - @Bind(R.id.trn_description) TextView mTransactionDescription; - @Bind(R.id.trn_time_and_date) TextView mTimeAndDate; - @Bind(R.id.trn_recurrence) TextView mRecurrence; - @Bind(R.id.trn_notes) TextView mNotes; - @Bind(R.id.toolbar) Toolbar mToolBar; - @Bind(R.id.transaction_account) TextView mTransactionAccount; - @Bind(R.id.balance_debit) TextView mDebitBalance; - @Bind(R.id.balance_credit) TextView mCreditBalance; + @BindView(R.id.trn_description) TextView mTransactionDescription; + @BindView(R.id.trn_time_and_date) TextView mTimeAndDate; + @BindView(R.id.trn_recurrence) TextView mRecurrence; + @BindView(R.id.trn_notes) TextView mNotes; + @BindView(R.id.toolbar) Toolbar mToolBar; + @BindView(R.id.transaction_account) TextView mTransactionAccount; + @BindView(R.id.balance_debit) TextView mDebitBalance; + @BindView(R.id.balance_credit) TextView mCreditBalance; - @Bind(R.id.fragment_transaction_details) + @BindView(R.id.fragment_transaction_details) TableLayout mDetailTableLayout; private String mTransactionUID; @@ -92,9 +92,9 @@ protected void onCreate(Bundle savedInstanceState) { } class SplitAmountViewHolder { - @Bind(R.id.split_account_name) TextView accountName; - @Bind(R.id.split_debit) TextView splitDebit; - @Bind(R.id.split_credit) TextView splitCredit; + @BindView(R.id.split_account_name) TextView accountName; + @BindView(R.id.split_debit) TextView splitDebit; + @BindView(R.id.split_credit) TextView splitCredit; View itemView; @@ -130,7 +130,8 @@ private void bindViews(){ LayoutInflater inflater = LayoutInflater.from(this); int index = 0; for (Split split : transaction.getSplits()) { - if (!useDoubleEntry && split.getAccountUID().equals(accountsDbAdapter.getImbalanceAccountUID(split.getValue().getCurrency()))){ + if (!useDoubleEntry && split.getAccountUID().equals( + accountsDbAdapter.getImbalanceAccountUID(split.getValue().getCommodity()))) { //do now show imbalance accounts for single entry use case continue; } diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 958fc62ff..14115deed 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -94,7 +94,7 @@ import java.util.GregorianCalendar; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -145,65 +145,65 @@ public class TransactionFormFragment extends Fragment implements /** * Button for setting the transaction type, either credit or debit */ - @Bind(R.id.input_transaction_type) TransactionTypeSwitch mTransactionTypeSwitch; + @BindView(R.id.input_transaction_type) TransactionTypeSwitch mTransactionTypeSwitch; /** * Input field for the transaction name (description) */ - @Bind(R.id.input_transaction_name) AutoCompleteTextView mDescriptionEditText; + @BindView(R.id.input_transaction_name) AutoCompleteTextView mDescriptionEditText; /** * Input field for the transaction amount */ - @Bind(R.id.input_transaction_amount) CalculatorEditText mAmountEditText; + @BindView(R.id.input_transaction_amount) CalculatorEditText mAmountEditText; /** * Field for the transaction currency. * The transaction uses the currency of the account */ - @Bind(R.id.currency_symbol) TextView mCurrencyTextView; + @BindView(R.id.currency_symbol) TextView mCurrencyTextView; /** * Input field for the transaction description (note) */ - @Bind(R.id.input_description) EditText mNotesEditText; + @BindView(R.id.input_description) EditText mNotesEditText; /** * Input field for the transaction date */ - @Bind(R.id.input_date) TextView mDateTextView; + @BindView(R.id.input_date) TextView mDateTextView; /** * Input field for the transaction time */ - @Bind(R.id.input_time) TextView mTimeTextView; + @BindView(R.id.input_time) TextView mTimeTextView; /** * Spinner for selecting the transfer account */ - @Bind(R.id.input_transfer_account_spinner) Spinner mTransferAccountSpinner; + @BindView(R.id.input_transfer_account_spinner) Spinner mTransferAccountSpinner; /** * Checkbox indicating if this transaction should be saved as a template or not */ - @Bind(R.id.checkbox_save_template) CheckBox mSaveTemplateCheckbox; + @BindView(R.id.checkbox_save_template) CheckBox mSaveTemplateCheckbox; - @Bind(R.id.input_recurrence) TextView mRecurrenceTextView; + @BindView(R.id.input_recurrence) TextView mRecurrenceTextView; /** * View which displays the calculator keyboard */ - @Bind(R.id.calculator_keyboard) KeyboardView mKeyboardView; + @BindView(R.id.calculator_keyboard) KeyboardView mKeyboardView; /** * Open the split editor */ - @Bind(R.id.btn_split_editor) ImageView mOpenSplitEditor; + @BindView(R.id.btn_split_editor) ImageView mOpenSplitEditor; /** * Layout for transfer account and associated views */ - @Bind(R.id.layout_double_entry) View mDoubleEntryLayout; + @BindView(R.id.layout_double_entry) View mDoubleEntryLayout; /** * Flag to note if double entry accounting is in use or not @@ -263,11 +263,11 @@ public void onClick(View v) { * Starts the transfer of funds from one currency to another */ private void startTransferFunds() { - Currency fromCurrency = Currency.getInstance(mTransactionsDbAdapter.getAccountCurrencyCode(mAccountUID)); + Commodity fromCommodity = Commodity.getInstance((mTransactionsDbAdapter.getAccountCurrencyCode(mAccountUID))); long id = mTransferAccountSpinner.getSelectedItemId(); - String targetCurrency = mAccountsDbAdapter.getCurrencyCode(mAccountsDbAdapter.getUID(id)); + String targetCurrencyCode = mAccountsDbAdapter.getCurrencyCode(mAccountsDbAdapter.getUID(id)); - if (fromCurrency.equals(Currency.getInstance(targetCurrency)) + if (fromCommodity.equals(Commodity.getInstance(targetCurrencyCode)) || !mAmountEditText.isInputModified() || mSplitQuantity != null) //if both accounts have same currency return; @@ -275,10 +275,10 @@ private void startTransferFunds() { BigDecimal amountBigd = mAmountEditText.getValue(); if (amountBigd.equals(BigDecimal.ZERO)) return; - Money amount = new Money(amountBigd, Commodity.getInstance(fromCurrency.getCurrencyCode())).abs(); + Money amount = new Money(amountBigd, fromCommodity).abs(); TransferFundsDialogFragment fragment - = TransferFundsDialogFragment.getInstance(amount, targetCurrency, this); + = TransferFundsDialogFragment.getInstance(amount, targetCurrencyCode, this); fragment.show(getFragmentManager(), "transfer_funds_editor"); } @@ -323,6 +323,10 @@ public void onActivityCreated(Bundle savedInstanceState) { @Override public void onItemSelected(AdapterView adapterView, View view, int position, long id) { + // Remove the favorite star from the view to avoid visual clutter. + TextView qualifiedAccountName = (TextView) view; + qualifiedAccountName.setCompoundDrawablesWithIntrinsicBounds(0,0,0,0); + if (mSplitsList.size() == 2) { //when handling simple transfer to one account for (Split split : mSplitsList) { if (!split.getAccountUID().equals(mAccountUID)) { @@ -457,7 +461,7 @@ private void initializeViewsWithTransaction(){ //when autocompleting, only change the amount if the user has not manually changed it already mAmountEditText.setValue(mTransaction.getBalance(mAccountUID).asBigDecimal()); } - mCurrencyTextView.setText(mTransaction.getCurrency().getSymbol()); + mCurrencyTextView.setText(mTransaction.getCommodity().getSymbol()); mNotesEditText.setText(mTransaction.getNote()); mDateTextView.setText(DATE_FORMATTER.format(mTransaction.getTimeMillis())); mTimeTextView.setText(TIME_FORMATTER.format(mTransaction.getTimeMillis())); @@ -472,7 +476,7 @@ private void initializeViewsWithTransaction(){ if (mSplitsList.size() == 2){ for (Split split : mSplitsList) { if (split.getAccountUID().equals(mAccountUID)) { - if (!split.getQuantity().getCurrency().equals(mTransaction.getCurrency())){ + if (!split.getQuantity().getCommodity().equals(mTransaction.getCommodity())){ mSplitQuantity = split.getQuantity(); } } @@ -492,8 +496,8 @@ private void initializeViewsWithTransaction(){ } String currencyCode = mTransactionsDbAdapter.getAccountCurrencyCode(mAccountUID); - Currency accountCurrency = Currency.getInstance(currencyCode); - mCurrencyTextView.setText(accountCurrency.getSymbol()); + Commodity accountCommodity = Commodity.getInstance(currencyCode); + mCurrencyTextView.setText(accountCommodity.getSymbol()); Commodity commodity = Commodity.getInstance(currencyCode); mAmountEditText.setCommodity(commodity); @@ -545,10 +549,9 @@ private void initalizeViews() { if (mAccountUID != null){ code = mTransactionsDbAdapter.getAccountCurrencyCode(mAccountUID); } - Currency accountCurrency = Currency.getInstance(code); - mCurrencyTextView.setText(accountCurrency.getSymbol()); - Commodity commodity = Commodity.getInstance(code); + Commodity commodity = Commodity.getInstance(code); + mCurrencyTextView.setText(commodity.getSymbol()); mAmountEditText.setCommodity(commodity); if (mUseDoubleEntry){ @@ -579,7 +582,7 @@ private void updateTransferAccountsList(){ if (mCursor != null) { mCursor.close(); } - mCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(conditions, new String[]{mAccountUID, AccountType.ROOT.name()}); + mCursor = mAccountsDbAdapter.fetchAccountsOrderedByFavoriteAndFullName(conditions, new String[]{mAccountUID, AccountType.ROOT.name()}); mAccountCursorAdapter = new QualifiedAccountNameCursorAdapter(getActivity(), mCursor); mTransferAccountSpinner.setAdapter(mAccountCursorAdapter); @@ -640,9 +643,9 @@ public void onClick(View v) { int year = calendar.get(Calendar.YEAR); int monthOfYear = calendar.get(Calendar.MONTH); int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH); - CalendarDatePickerDialogFragment datePickerDialog = CalendarDatePickerDialogFragment.newInstance( - TransactionFormFragment.this, - year, monthOfYear, dayOfMonth); + CalendarDatePickerDialogFragment datePickerDialog = new CalendarDatePickerDialogFragment() + .setOnDateSetListener(TransactionFormFragment.this) + .setPreselectedDate(year, monthOfYear, dayOfMonth); datePickerDialog.show(getFragmentManager(), "date_picker_fragment"); } }); @@ -662,9 +665,10 @@ public void onClick(View v) { Calendar calendar = Calendar.getInstance(); calendar.setTimeInMillis(timeMillis); - RadialTimePickerDialogFragment timePickerDialog = RadialTimePickerDialogFragment.newInstance( - TransactionFormFragment.this, calendar.get(Calendar.HOUR_OF_DAY), - calendar.get(Calendar.MINUTE), true); + RadialTimePickerDialogFragment timePickerDialog = new RadialTimePickerDialogFragment() + .setOnTimeSetListener(TransactionFormFragment.this) + .setStartTime(calendar.get(Calendar.HOUR_OF_DAY), + calendar.get(Calendar.MINUTE)); timePickerDialog.show(getFragmentManager(), "time_picker_dialog_fragment"); } }); @@ -739,8 +743,8 @@ private List extractSplitsFromView(){ long transferAcctId = mTransferAccountSpinner.getSelectedItemId(); transferAcctUID = mAccountsDbAdapter.getUID(transferAcctId); } else { - String baseCurrencyCode = mTransactionsDbAdapter.getAccountCurrencyCode(mAccountUID); - transferAcctUID = mAccountsDbAdapter.getOrCreateImbalanceAccountUID(Currency.getInstance(baseCurrencyCode)); + Commodity baseCommodity = mAccountsDbAdapter.getRecord(mAccountUID).getCommodity(); + transferAcctUID = mAccountsDbAdapter.getOrCreateImbalanceAccountUID(baseCommodity); } return transferAcctUID; } @@ -767,7 +771,6 @@ private List extractSplitsFromView(){ Transaction transaction = new Transaction(description); transaction.setTime(cal.getTimeInMillis()); transaction.setCommodity(commodity); - transaction.setCurrencyCode(currencyCode); transaction.setNote(notes); transaction.setSplits(splits); transaction.setExported(false); //not necessary as exports use timestamps now. Because, legacy diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsActivity.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsActivity.java index 7a071296f..060d5a707 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsActivity.java @@ -66,7 +66,7 @@ import java.text.SimpleDateFormat; import java.util.Date; -import butterknife.Bind; +import butterknife.BindView; /** * Activity for displaying, creating and editing transactions @@ -111,11 +111,11 @@ public class TransactionsActivity extends BaseDrawerActivity implements */ private Cursor mAccountsCursor = null; - @Bind(R.id.pager) ViewPager mViewPager; - @Bind(R.id.toolbar_spinner) Spinner mToolbarSpinner; - @Bind(R.id.tab_layout) TabLayout mTabLayout; - @Bind(R.id.transactions_sum) TextView mSumTextView; - @Bind(R.id.fab_create_transaction) FloatingActionButton mCreateFloatingButton; + @BindView(R.id.pager) ViewPager mViewPager; + @BindView(R.id.toolbar_spinner) Spinner mToolbarSpinner; + @BindView(R.id.tab_layout) TabLayout mTabLayout; + @BindView(R.id.transactions_sum) TextView mSumTextView; + @BindView(R.id.fab_create_transaction) FloatingActionButton mCreateFloatingButton; private SparseArray mFragmentPageReferenceMap = new SparseArray<>(); @@ -143,6 +143,8 @@ public void onItemSelected(AdapterView parent, View view, int position, long mTabLayout.addTab(mTabLayout.newTab().setText(R.string.section_header_transactions)); } } + // Hide the favorite icon of the selected account to avoid clutter + ((TextView) view).setCompoundDrawablesWithIntrinsicBounds(0,0,0,0); //refresh any fragments in the tab with the new account UID refresh(); } diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsListFragment.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsListFragment.java index 8d27d592d..bb5796009 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsListFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionsListFragment.java @@ -63,7 +63,7 @@ import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -85,7 +85,7 @@ public class TransactionsListFragment extends Fragment implements private boolean mUseCompactView = false; private TransactionRecyclerAdapter mTransactionRecyclerAdapter; - @Bind(R.id.transaction_recycler_view) EmptyRecyclerView mRecyclerView; + @BindView(R.id.transaction_recycler_view) EmptyRecyclerView mRecyclerView; @Override @@ -323,14 +323,14 @@ public void onClick(View v) { } public class ViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener{ - @Bind(R.id.primary_text) public TextView primaryText; - @Bind(R.id.secondary_text) public TextView secondaryText; - @Bind(R.id.transaction_amount) public TextView transactionAmount; - @Bind(R.id.options_menu) public ImageView optionsMenu; + @BindView(R.id.primary_text) public TextView primaryText; + @BindView(R.id.secondary_text) public TextView secondaryText; + @BindView(R.id.transaction_amount) public TextView transactionAmount; + @BindView(R.id.options_menu) public ImageView optionsMenu; //these views are not used in the compact view, hence the nullability - @Nullable @Bind(R.id.transaction_date) public TextView transactionDate; - @Nullable @Bind(R.id.edit_transaction) public ImageView editTransaction; + @Nullable @BindView(R.id.transaction_date) public TextView transactionDate; + @Nullable @BindView(R.id.edit_transaction) public ImageView editTransaction; long transactionId; diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/dialog/TransferFundsDialogFragment.java b/app/src/main/java/org/gnucash/android/ui/transaction/dialog/TransferFundsDialogFragment.java index fcbe8766b..234dd892c 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/dialog/TransferFundsDialogFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/dialog/TransferFundsDialogFragment.java @@ -50,7 +50,7 @@ import java.text.ParseException; import java.util.Currency; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -59,24 +59,24 @@ */ public class TransferFundsDialogFragment extends DialogFragment { - @Bind(R.id.from_currency) TextView mFromCurrencyLabel; - @Bind(R.id.to_currency) TextView mToCurrencyLabel; - @Bind(R.id.target_currency) TextView mConvertedAmountCurrencyLabel; - @Bind(R.id.amount_to_convert) TextView mStartAmountLabel; - @Bind(R.id.input_exchange_rate) EditText mExchangeRateInput; - @Bind(R.id.input_converted_amount) EditText mConvertedAmountInput; - @Bind(R.id.btn_fetch_exchange_rate) Button mFetchExchangeRateButton; - @Bind(R.id.radio_exchange_rate) RadioButton mExchangeRateRadioButton; - @Bind(R.id.radio_converted_amount) RadioButton mConvertedAmountRadioButton; - @Bind(R.id.label_exchange_rate_example) + @BindView(R.id.from_currency) TextView mFromCurrencyLabel; + @BindView(R.id.to_currency) TextView mToCurrencyLabel; + @BindView(R.id.target_currency) TextView mConvertedAmountCurrencyLabel; + @BindView(R.id.amount_to_convert) TextView mStartAmountLabel; + @BindView(R.id.input_exchange_rate) EditText mExchangeRateInput; + @BindView(R.id.input_converted_amount) EditText mConvertedAmountInput; + @BindView(R.id.btn_fetch_exchange_rate) Button mFetchExchangeRateButton; + @BindView(R.id.radio_exchange_rate) RadioButton mExchangeRateRadioButton; + @BindView(R.id.radio_converted_amount) RadioButton mConvertedAmountRadioButton; + @BindView(R.id.label_exchange_rate_example) TextView mSampleExchangeRate; - @Bind(R.id.exchange_rate_text_input_layout) + @BindView(R.id.exchange_rate_text_input_layout) TextInputLayout mExchangeRateInputLayout; - @Bind(R.id.converted_amount_text_input_layout) + @BindView(R.id.converted_amount_text_input_layout) TextInputLayout mConvertedAmountInputLayout; - @Bind(R.id.btn_save) Button mSaveButton; - @Bind(R.id.btn_cancel) Button mCancelButton; + @BindView(R.id.btn_save) Button mSaveButton; + @BindView(R.id.btn_cancel) Button mCancelButton; Money mOriginAmount; String mTargetCurrencyCode; @@ -99,7 +99,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ButterKnife.bind(this, view); TransactionsActivity.displayBalance(mStartAmountLabel, mOriginAmount); - String fromCurrencyCode = mOriginAmount.getCurrency().getCurrencyCode(); + String fromCurrencyCode = mOriginAmount.getCommodity().getCurrencyCode(); mFromCurrencyLabel.setText(fromCurrencyCode); mToCurrencyLabel.setText(mTargetCurrencyCode); mConvertedAmountCurrencyLabel.setText(mTargetCurrencyCode); @@ -198,7 +198,7 @@ private void transferFunds() { Price price = null; CommoditiesDbAdapter commoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); - String originCommodityUID = commoditiesDbAdapter.getCommodityUID(mOriginAmount.getCurrency().getCurrencyCode()); + String originCommodityUID = mOriginAmount.getCommodity().getUID(); String targetCommodityUID = commoditiesDbAdapter.getCommodityUID(mTargetCurrencyCode); if (mExchangeRateRadioButton.isChecked()) { diff --git a/app/src/main/java/org/gnucash/android/ui/util/RecurrenceParser.java b/app/src/main/java/org/gnucash/android/ui/util/RecurrenceParser.java index 379dd60f7..2855b7115 100644 --- a/app/src/main/java/org/gnucash/android/ui/util/RecurrenceParser.java +++ b/app/src/main/java/org/gnucash/android/ui/util/RecurrenceParser.java @@ -78,8 +78,8 @@ public static Recurrence parse(EventRecurrence eventRecurrence){ } int interval = eventRecurrence.interval == 0 ? 1 : eventRecurrence.interval; //bug from betterpickers library sometimes returns 0 as the interval - periodType.setMultiplier(interval); Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier(interval); parseEndTime(eventRecurrence, recurrence); recurrence.setByDays(parseByDay(eventRecurrence.byday)); if (eventRecurrence.startDate != null) diff --git a/app/src/main/java/org/gnucash/android/ui/util/dialog/DateRangePickerDialogFragment.java b/app/src/main/java/org/gnucash/android/ui/util/dialog/DateRangePickerDialogFragment.java index 1447119d1..ba64ebe94 100644 --- a/app/src/main/java/org/gnucash/android/ui/util/dialog/DateRangePickerDialogFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/util/dialog/DateRangePickerDialogFragment.java @@ -35,7 +35,7 @@ import java.util.Date; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -45,9 +45,9 @@ */ public class DateRangePickerDialogFragment extends DialogFragment{ - @Bind(R.id.calendar_view) CalendarPickerView mCalendarPickerView; - @Bind(R.id.btn_save) Button mDoneButton; - @Bind(R.id.btn_cancel) Button mCancelButton; + @BindView(R.id.calendar_view) CalendarPickerView mCalendarPickerView; + @BindView(R.id.btn_save) Button mDoneButton; + @BindView(R.id.btn_cancel) Button mCancelButton; private Date mStartRange = LocalDate.now().minusMonths(1).toDate(); private Date mEndRange = LocalDate.now().toDate(); diff --git a/app/src/main/java/org/gnucash/android/ui/wizard/FirstRunWizardActivity.java b/app/src/main/java/org/gnucash/android/ui/wizard/FirstRunWizardActivity.java index 9284990e3..9efa3c81b 100644 --- a/app/src/main/java/org/gnucash/android/ui/wizard/FirstRunWizardActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/wizard/FirstRunWizardActivity.java @@ -55,7 +55,7 @@ import java.util.ArrayList; import java.util.List; -import butterknife.Bind; +import butterknife.BindView; import butterknife.ButterKnife; /** @@ -64,7 +64,7 @@ public class FirstRunWizardActivity extends AppCompatActivity implements PageFragmentCallbacks, ReviewFragment.Callbacks, ModelCallbacks { - @Bind(R.id.pager) ViewPager mPager; + @BindView(R.id.pager) ViewPager mPager; private MyPagerAdapter mPagerAdapter; private boolean mEditingAfterReview; @@ -73,9 +73,9 @@ public class FirstRunWizardActivity extends AppCompatActivity implements private boolean mConsumePageSelectedEvent; - @Bind(R.id.btn_save) AppCompatButton mNextButton; - @Bind(R.id.btn_cancel) Button mPrevButton; - @Bind(R.id.strip) StepPagerStrip mStepPagerStrip; + @BindView(R.id.btn_save) AppCompatButton mNextButton; + @BindView(R.id.btn_cancel) Button mPrevButton; + @BindView(R.id.strip) StepPagerStrip mStepPagerStrip; private List mCurrentPageSequence; private String mAccountOptions; @@ -228,7 +228,8 @@ private void createAccountsAndFinish() { finish(); } else if (mAccountOptions.equals(getString(R.string.wizard_option_import_my_accounts))){ AccountsActivity.startXmlFileChooser(this); - } else { + } else { //user prefers to handle account creation themselves + AccountsActivity.start(this); finish(); } } diff --git a/app/src/main/java/org/gnucash/android/util/CommoditiesCursorAdapter.java b/app/src/main/java/org/gnucash/android/util/CommoditiesCursorAdapter.java index ddc548950..03f16608c 100644 --- a/app/src/main/java/org/gnucash/android/util/CommoditiesCursorAdapter.java +++ b/app/src/main/java/org/gnucash/android/util/CommoditiesCursorAdapter.java @@ -24,8 +24,8 @@ import android.view.View; import android.widget.TextView; -import org.gnucash.android.db.adapter.CommoditiesDbAdapter; import org.gnucash.android.db.DatabaseSchema; +import org.gnucash.android.db.adapter.CommoditiesDbAdapter; /** * Cursor adapter for displaying list of commodities. diff --git a/app/src/main/java/org/gnucash/android/util/PreferencesHelper.java b/app/src/main/java/org/gnucash/android/util/PreferencesHelper.java index 27be8b7bd..9214750c7 100644 --- a/app/src/main/java/org/gnucash/android/util/PreferencesHelper.java +++ b/app/src/main/java/org/gnucash/android/util/PreferencesHelper.java @@ -37,7 +37,7 @@ private PreferencesHelper() {} /** * Tag for logging */ - protected static final String LOG_TAG = "PreferencesHelper"; + private static final String LOG_TAG = "PreferencesHelper"; /** * Preference key for saving the last export time @@ -52,14 +52,13 @@ private PreferencesHelper() {} * @see #setLastExportTime(Timestamp, String) */ public static void setLastExportTime(Timestamp lastExportTime) { - final String utcString = TimestampHelper.getUtcStringFromTimestamp(lastExportTime); Log.v(LOG_TAG, "Saving last export time for the currently active book"); setLastExportTime(lastExportTime, BooksDbAdapter.getInstance().getActiveBookUID()); } /** * Set the last export time in UTC time zone for a specific book. - * This value vill be used during export to determine new transactions since the last export + * This value will be used during export to determine new transactions since the last export * * @param lastExportTime the last export time to set. */ diff --git a/app/src/main/java/org/gnucash/android/util/QualifiedAccountNameCursorAdapter.java b/app/src/main/java/org/gnucash/android/util/QualifiedAccountNameCursorAdapter.java index a2b310932..dcf17c13d 100644 --- a/app/src/main/java/org/gnucash/android/util/QualifiedAccountNameCursorAdapter.java +++ b/app/src/main/java/org/gnucash/android/util/QualifiedAccountNameCursorAdapter.java @@ -68,6 +68,13 @@ public void bindView(View view, Context context, Cursor cursor) { super.bindView(view, context, cursor); TextView textView = (TextView) view.findViewById(android.R.id.text1); textView.setEllipsize(TextUtils.TruncateAt.MIDDLE); + + Integer isFavorite = cursor.getInt(cursor.getColumnIndex(DatabaseSchema.AccountEntry.COLUMN_FAVORITE)); + if(isFavorite == 0) { + textView.setCompoundDrawablesWithIntrinsicBounds(0,0,0,0); + } else { + textView.setCompoundDrawablesWithIntrinsicBounds(0,0,R.drawable.ic_star_black_24dp,0); + } } /** diff --git a/app/src/main/jniLibs/armeabi-v7a/libDropboxSync.so b/app/src/main/jniLibs/armeabi-v7a/libDropboxSync.so deleted file mode 100644 index 45d1a6fe8..000000000 Binary files a/app/src/main/jniLibs/armeabi-v7a/libDropboxSync.so and /dev/null differ diff --git a/app/src/main/jniLibs/armeabi/libDropboxSync.so b/app/src/main/jniLibs/armeabi/libDropboxSync.so deleted file mode 100644 index b4440e8d9..000000000 Binary files a/app/src/main/jniLibs/armeabi/libDropboxSync.so and /dev/null differ diff --git a/app/src/main/jniLibs/mips/libDropboxSync.so b/app/src/main/jniLibs/mips/libDropboxSync.so deleted file mode 100644 index 80b4b187f..000000000 Binary files a/app/src/main/jniLibs/mips/libDropboxSync.so and /dev/null differ diff --git a/app/src/main/jniLibs/x86/libDropboxSync.so b/app/src/main/jniLibs/x86/libDropboxSync.so deleted file mode 100644 index 1861422b8..000000000 Binary files a/app/src/main/jniLibs/x86/libDropboxSync.so and /dev/null differ diff --git a/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png new file mode 100644 index 000000000..bbfbc96cb Binary files /dev/null and b/app/src/main/res/drawable-hdpi/ic_search_white_24dp.png differ diff --git a/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png new file mode 100644 index 000000000..faefc59c8 Binary files /dev/null and b/app/src/main/res/drawable-mdpi/ic_search_white_24dp.png differ diff --git a/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png new file mode 100644 index 000000000..bfc3e3939 Binary files /dev/null and b/app/src/main/res/drawable-xhdpi/ic_search_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png new file mode 100644 index 000000000..abbb98951 Binary files /dev/null and b/app/src/main/res/drawable-xxhdpi/ic_search_white_24dp.png differ diff --git a/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png b/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png new file mode 100644 index 000000000..dd5adfc7f Binary files /dev/null and b/app/src/main/res/drawable-xxxhdpi/ic_search_white_24dp.png differ diff --git a/app/src/main/res/layout/widget_4x1.xml b/app/src/main/res/layout/widget_4x1.xml index 3a9343a88..0d5cb9f29 100644 --- a/app/src/main/res/layout/widget_4x1.xml +++ b/app/src/main/res/layout/widget_4x1.xml @@ -54,5 +54,14 @@ android:src="@drawable/content_new_holo_light" android:background="@drawable/appwidget_bg_clickable" android:contentDescription="@string/description_add_transaction_icon"/> + + \ No newline at end of file diff --git a/app/src/main/res/layout/widget_configuration.xml b/app/src/main/res/layout/widget_configuration.xml index f9ef7c19f..41fb96e0f 100644 --- a/app/src/main/res/layout/widget_configuration.xml +++ b/app/src/main/res/layout/widget_configuration.xml @@ -50,5 +50,13 @@ android:layout_height="wrap_content" android:minHeight="?android:attr/listPreferredItemHeight" /> + + \ No newline at end of file diff --git a/app/src/main/res/menu/global_actions.xml b/app/src/main/res/menu/global_actions.xml index 1a0d6dc4d..da2b9bc56 100644 --- a/app/src/main/res/menu/global_actions.xml +++ b/app/src/main/res/menu/global_actions.xml @@ -20,7 +20,7 @@ diff --git a/app/src/main/res/raw-es-rES/default_accounts.gnucash b/app/src/main/res/raw-es/default_accounts.gnucash similarity index 100% rename from app/src/main/res/raw-es-rES/default_accounts.gnucash rename to app/src/main/res/raw-es/default_accounts.gnucash diff --git a/app/src/main/res/raw-fr-rFR/default_accounts.gnucash b/app/src/main/res/raw-fr/default_accounts.gnucash similarity index 100% rename from app/src/main/res/raw-fr-rFR/default_accounts.gnucash rename to app/src/main/res/raw-fr/default_accounts.gnucash diff --git a/app/src/main/res/raw-pt/default_accounts.gnucash b/app/src/main/res/raw-pt/default_accounts.gnucash new file mode 100644 index 000000000..75b458c6c --- /dev/null +++ b/app/src/main/res/raw-pt/default_accounts.gnucash @@ -0,0 +1,854 @@ + + + +1 +62 + + ISO4217 + BRL + + currency + + + + template + template + template + template + 1 + + + Root Account + 952a25db819d0987b080a73807fa49ef + ROOT + + + Ativos + 2ca8165b9bf259a5338b560bcb00917b + ASSET + + ISO4217 + BRL + + 100 + Ativos + + + placeholder + true + + + color + #1469EB + + + 952a25db819d0987b080a73807fa49ef + + + Ativos Atuais + 9c0853e895fe1d4990debd0127ce5e3b + ASSET + + ISO4217 + BRL + + 100 + Ativos Atuais + 2ca8165b9bf259a5338b560bcb00917b + + + Conta Corrente + 4d849998e7fee25043cbc86af06e7fc0 + BANK + + ISO4217 + BRL + + 100 + Conta Corrente + 9c0853e895fe1d4990debd0127ce5e3b + + + Conta Poupança + 9a81748289eafdcc5f2c5f583af2790f + BANK + + ISO4217 + BRL + + 100 + Conta Poupança + 9c0853e895fe1d4990debd0127ce5e3b + + + Dinheiro na Carteira + 1423ea7c1319b7e1a507d2cef8c6e610 + CASH + + ISO4217 + BRL + + 100 + Dinheiro na Carteira + 9c0853e895fe1d4990debd0127ce5e3b + + + Passivo + f519bd242dee11fdf00b22f9c0d7f184 + LIABILITY + + ISO4217 + BRL + + 100 + Passivo + + + placeholder + true + + + color + #B304AD + + + 952a25db819d0987b080a73807fa49ef + + + Contas a Pagar + 7edb20707c791c3ca19267506fd8c8ff + LIABILITY + + ISO4217 + BRL + + 100 + Contas a Pagar + f519bd242dee11fdf00b22f9c0d7f184 + + + Cartão de Crédito + e9472a3ad501e82750423eff1cecdae8 + CREDIT + + ISO4217 + BRL + + 100 + Cartão de Crédito + 7edb20707c791c3ca19267506fd8c8ff + + + Receitas + cd991e82a7010d7a5a6a372488cd28ac + INCOME + + ISO4217 + BRL + + 100 + Receitas + + + color + #1B4F15 + + + placeholder + true + + + 952a25db819d0987b080a73807fa49ef + + + Bônus + 5423b9bcd6c37f18c066d9f95b228065 + INCOME + + ISO4217 + BRL + + 100 + Bônus + cd991e82a7010d7a5a6a372488cd28ac + + + Presentes Recebidos + f522959a85b82818dd87acbbf5f1a1fd + INCOME + + ISO4217 + BRL + + 100 + Presentes Recebidos + cd991e82a7010d7a5a6a372488cd28ac + + + Juros Recebidos + abb14d23450baa9b350f68af916a45d7 + INCOME + + ISO4217 + BRL + + 100 + Juros Recebidos + cd991e82a7010d7a5a6a372488cd28ac + + + Juros Conta Corrente + 16205f4eb218c90532dcbc8699fbea8b + INCOME + + ISO4217 + BRL + + 100 + Juros Conta Corrente + abb14d23450baa9b350f68af916a45d7 + + + Outros Juros + 7ad757be43dba4e5574ef137be355cee + INCOME + + ISO4217 + BRL + + 100 + Outros Juros + abb14d23450baa9b350f68af916a45d7 + + + Juros Conta Poupança + 5fc46cd847b81b70ffccc7b9ac255c6a + INCOME + + ISO4217 + BRL + + 100 + Juros Conta Poupança + abb14d23450baa9b350f68af916a45d7 + + + Outras Receitas + ba0811f3443b07b5be7709dfdd7e7900 + INCOME + + ISO4217 + BRL + + 100 + Outras Receitas + cd991e82a7010d7a5a6a372488cd28ac + + + Salário + 341f2d0617897e03a791e7269a91abdd + INCOME + + ISO4217 + BRL + + 100 + Salário + cd991e82a7010d7a5a6a372488cd28ac + + + Despesas + af01f680c19671e931dcbc717c1670c1 + EXPENSE + + ISO4217 + BRL + + 100 + Despesas + + + placeholder + true + + + color + #D13E29 + + + 952a25db819d0987b080a73807fa49ef + + + Ajustes + b86045be792b11d225aae6401f00c11d + EXPENSE + + ISO4217 + BRL + + 100 + Ajustes + af01f680c19671e931dcbc717c1670c1 + + + Automóvel + 16d60ae856f830823cbe134a931b607a + EXPENSE + + ISO4217 + BRL + + 100 + Automóvel + af01f680c19671e931dcbc717c1670c1 + + + Impostos + 522b04e086860e4cb2f291e910632191 + EXPENSE + + ISO4217 + BRL + + 100 + Impostos + 16d60ae856f830823cbe134a931b607a + + + IRF + 51f11cd9ff63e40df33c4f9bb85ffae5 + EXPENSE + + ISO4217 + BRL + + 100 + IRF + 522b04e086860e4cb2f291e910632191 + + + INSS + dc03d2ac1746c7443090b936c45d6e47 + EXPENSE + + ISO4217 + BRL + + 100 + INSS + 522b04e086860e4cb2f291e910632191 + + + Outros Impostos + 1b1a394355720050623bbf8efd5db96f + EXPENSE + + ISO4217 + BRL + + 100 + Outros Impostos + 522b04e086860e4cb2f291e910632191 + + + CPMF + 5e35e034e1f35cb764039b2e3138ea2e + EXPENSE + + ISO4217 + BRL + + 100 + CPMF + 522b04e086860e4cb2f291e910632191 + + + Combustível + 5095ea251343d06066825c1648377f72 + EXPENSE + + ISO4217 + BRL + + 100 + Combustível + 16d60ae856f830823cbe134a931b607a + + + Estacionamento + f029089f5a0e6cbbc30294731268040c + EXPENSE + + ISO4217 + BRL + + 100 + Estacionamento + 16d60ae856f830823cbe134a931b607a + + + Reparos e Manutenção + b11c94186e2d3748616cd28daa1971ab + EXPENSE + + ISO4217 + BRL + + 100 + Reparos e Manutenção + 16d60ae856f830823cbe134a931b607a + + + Taxas Bancárias + 58f90bef2f673a626de4f01ffbd70c0a + EXPENSE + + ISO4217 + BRL + + 100 + Taxas Bancárias + af01f680c19671e931dcbc717c1670c1 + + + Livros + b4007b0565efa36b19e7521def252391 + EXPENSE + + ISO4217 + BRL + + 100 + Livros + af01f680c19671e931dcbc717c1670c1 + + + Tv por assinatura + 5786c8e897b615b0f0119ab45d791b43 + EXPENSE + + ISO4217 + BRL + + 100 + Tv por assinatura + af01f680c19671e931dcbc717c1670c1 + + + Doações + 688471254b035f00debc808c6a0b5c00 + EXPENSE + + ISO4217 + BRL + + 100 + Doações + af01f680c19671e931dcbc717c1670c1 + + + Vestuário + d8b8ce667284fcec70aef00b5f4a0354 + EXPENSE + + ISO4217 + BRL + + 100 + Vestuário + af01f680c19671e931dcbc717c1670c1 + + + Computador + 2c00a7fc74b0ac781492c60b5e87cfd2 + EXPENSE + + ISO4217 + BRL + + 100 + Computador + af01f680c19671e931dcbc717c1670c1 + + + Refeições Fora + cb130366ceb6fd786552eabf63e7645b + EXPENSE + + ISO4217 + BRL + + 100 + Refeições Fora + af01f680c19671e931dcbc717c1670c1 + + + Educação + 816e0e35d103868c1c9928d23bf27cae + EXPENSE + + ISO4217 + BRL + + 100 + Educação + af01f680c19671e931dcbc717c1670c1 + + + Diversão + 91176512e4c80e0504ed3092f7a6e002 + EXPENSE + + ISO4217 + BRL + + 100 + Diversão + af01f680c19671e931dcbc717c1670c1 + + + Música/Cinema + c0d44d5ce0bec5f6f740e66b01f844db + EXPENSE + + ISO4217 + BRL + + 100 + Música/Cinema + 91176512e4c80e0504ed3092f7a6e002 + + + Passeios + e8d1adb3429f88cedc58ad798f241a6b + EXPENSE + + ISO4217 + BRL + + 100 + Passeios + 91176512e4c80e0504ed3092f7a6e002 + + + Viagens + 48b3bdf8019d15166dbb419436d67131 + EXPENSE + + ISO4217 + BRL + + 100 + Viagens + 91176512e4c80e0504ed3092f7a6e002 + + + Presentes + 8f06a81652b7413269ec3f54f76c4e54 + EXPENSE + + ISO4217 + BRL + + 100 + Presentes + af01f680c19671e931dcbc717c1670c1 + + + Mercearia + 7df0116685a1cb8e262018e2bb05a0cb + EXPENSE + + ISO4217 + BRL + + 100 + Mercearia + af01f680c19671e931dcbc717c1670c1 + + + Passatempos + 32b7f3200c39e04083a786b8a67f6fa4 + EXPENSE + + ISO4217 + BRL + + 100 + Passatempos + af01f680c19671e931dcbc717c1670c1 + + + Seguro + 21772b4c902c42f2f99aae496ace34a5 + EXPENSE + + ISO4217 + BRL + + 100 + Seguro + af01f680c19671e931dcbc717c1670c1 + + + Seguro Automóvel + d254b6c761f104288d1a33d17359ef32 + EXPENSE + + ISO4217 + BRL + + 100 + Seguro Automóvel + 21772b4c902c42f2f99aae496ace34a5 + + + Seguro Saúde + 7bf48e3734165cdac9c075991ac365b1 + EXPENSE + + ISO4217 + BRL + + 100 + Seguro Saúde + 21772b4c902c42f2f99aae496ace34a5 + + + Seguro de Vida + 7e240151044548c4ec54c0cfd478b852 + EXPENSE + + ISO4217 + BRL + + 100 + Seguro de Vida + 21772b4c902c42f2f99aae496ace34a5 + + + Lavandaria + 02e7db3b7f6535bf5477f6912a4b9811 + EXPENSE + + ISO4217 + BRL + + 100 + Lavandaria + af01f680c19671e931dcbc717c1670c1 + + + Despesas com Saúde + bdb225e5284388f41520d8babf88b569 + EXPENSE + + ISO4217 + BRL + + 100 + Despesas com Saúde + af01f680c19671e931dcbc717c1670c1 + + + Outras + 5ace6b588047a5442795abe8e95bcd87 + EXPENSE + + ISO4217 + BRL + + 100 + Outras + af01f680c19671e931dcbc717c1670c1 + + + Internet + 8e4a5f429df5477ef384c68804033912 + EXPENSE + + ISO4217 + BRL + + 100 + Internet + af01f680c19671e931dcbc717c1670c1 + + + Telefone + 1bba532c883f2db5975918714edd358a + EXPENSE + + ISO4217 + BRL + + 100 + Telefone + af01f680c19671e931dcbc717c1670c1 + + + Transportes Públicos + eb0c6015eed4fbb0993ed35c6f1d1565 + EXPENSE + + ISO4217 + BRL + + 100 + Transportes Públicos + af01f680c19671e931dcbc717c1670c1 + + + Assinaturas + 96a9ba0dfb3e81d3d326e0a43be4b0c9 + EXPENSE + + ISO4217 + BRL + + 100 + Assinaturas de jornais, revistas... + af01f680c19671e931dcbc717c1670c1 + + + Material de Escritório + abe8c26bfbce7bf7c146fe079237b7d8 + EXPENSE + + ISO4217 + BRL + + 100 + Material de Escritório + af01f680c19671e931dcbc717c1670c1 + + + Serviços + 6f7d22171348352d7c38fa7f9f8a65d9 + EXPENSE + + ISO4217 + BRL + + 100 + Serviços + af01f680c19671e931dcbc717c1670c1 + + + Eletricidade + ce02a74d7605d5913a2868c9abb429aa + EXPENSE + + ISO4217 + BRL + + 100 + Eletricidade + 6f7d22171348352d7c38fa7f9f8a65d9 + + + Gás + 083481a43e952b8b797fb1cfba9f2740 + EXPENSE + + ISO4217 + BRL + + 100 + Gás + 6f7d22171348352d7c38fa7f9f8a65d9 + + + Água + 1939e56e10b4fb0ee262043976482e90 + EXPENSE + + ISO4217 + BRL + + 100 + Água + 6f7d22171348352d7c38fa7f9f8a65d9 + + + Líquido + 7b9c1b1d9fc25d42ecfad36fe59da0af + EQUITY + + ISO4217 + BRL + + 100 + Líquido + + + placeholder + true + + + color + #EE8600 + + + 952a25db819d0987b080a73807fa49ef + + + Saldos Iniciais + a93bfef1115ba7862fae8cbb24d24c06 + EQUITY + + ISO4217 + BRL + + 100 + Saldos Iniciais + 7b9c1b1d9fc25d42ecfad36fe59da0af + + + + + + diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index 0c1a4909f..e151c2ad3 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -478,4 +480,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml index 63d419231..079a103a2 100644 --- a/app/src/main/res/values-ar-rSA/strings.xml +++ b/app/src/main/res/values-ar-rSA/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -506,4 +508,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index 84e02fd33..03478673f 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -21,6 +21,7 @@ Informació Exporta… Afegeix un assentament nou al compte + View account details No hi ha comptes per mostrar Nom del compte Cancel·la @@ -63,7 +64,7 @@ Preferències Targeta SD - DropBox + Dropbox Google Drive ownCloud Envia a… @@ -85,6 +86,7 @@ Registrar transaccions en GnuCash Crear comptes en GnuCash Display account + Hide account balance in widget Crea els comptes Seleccioneu els comptes a crear No hi ha comptes en GnuCash.\nCreeu un compte abans d\'afegir un giny @@ -476,4 +478,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index a21786e46..7ac3d8731 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -16,11 +16,12 @@ limitations under the License. --> - Create Account - Edit Account + Vytvořit účet + Upravit účet Čestina - Export… - Add a new transaction to an account + Exportovat… + Přidat novou transakci na účet + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -485,4 +487,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 38659a210..9be4749df 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -21,6 +21,7 @@ Info OFX-Datei exportieren Neue Buchung in ein Konto + View account details Keine Konten vorhanden Kontoname Abbrechen @@ -63,7 +64,7 @@ Einstellungen SD-Kartenspeicher - DropBox + Dropbox Google Drive ownCloud Senden an… @@ -85,6 +86,7 @@ Buchungen speichern in GnuCash Konten in GnuCash erstellen Konto anzeigen + Hide account balance in widget Konten erstellen Zu erstellende Konten auswählen Keine Konten vorhanden.\nErstellen Sie ein Konto um Widgets hinzuzufügen @@ -475,4 +477,5 @@ No user-identifiable information will be collected as part of this process!%1$s mal
Kompakte Ansicht Buch %1$d + never diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index 05fdf60d8..dc325e643 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -21,6 +21,7 @@ Πληροφορίες Εξαγωγή OFX Προσθήκη μιας νέας συναλλαγής σε ένα λογαριασμό + View account details Δεν υπάρχουν λογαριασμοί για εμφάνιση Όνομα λογαριασμού Ακύρωση @@ -63,7 +64,7 @@ Ρυθμίσεις Κάρτα SD - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Καταγραφή συναλλαγών στο GnuCash Δημιουργία λογαριασμών στο GnuCash Εμφάνιση λογαριασμού + Hide account balance in widget Δημιουργία Λογαριασμών Επιλογή λογαριασμών για δημιουργία Δεν υπάρχουν λογαριασμοί στο @@ -489,4 +491,5 @@ No user-identifiable information will be collected as part of this process! for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 90a0d4a3f..7f6696157 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -478,4 +480,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-es-rMX/strings.xml b/app/src/main/res/values-es-rMX/strings.xml index 68f76a3bb..826ba8753 100644 --- a/app/src/main/res/values-es-rMX/strings.xml +++ b/app/src/main/res/values-es-rMX/strings.xml @@ -21,6 +21,7 @@ Detalles Exportar… Añadir una nueva transacción a una cuenta + View account details No hay cuentas que mostrar Nombre de la cuenta Cancelar @@ -63,7 +64,7 @@ Ajustes Tarjeta SD - DropBox + Dropbox Google Drive ownCloud Enviar a… @@ -85,6 +86,7 @@ Registrar transacciones en GnuCash Crear cuentas en GnuCash Mostrar cuentas + Hide account balance in widget Crear Cuentas Seleccionar cuentas a crear No hay cuentas en Gnucash.\nCree una cuenta antes de añadir un widget @@ -437,41 +439,42 @@ Este proceso solo recoge información que no permite identificar al usuarioWXYZ 0 + - Manage Books - Manage Books… - Select any part of the chart to view details - Confirm delete Book - All accounts and transactions in this book will be deleted! - Delete Book - Last Exported: - Enable Sync - New Book - The selected transaction has no splits and cannot be opened - %1$d splits - in %1$s + Administrar libros + Administrar libros… + Seleccione cualquier parte del gráfico para ver los detalles + Confirmar borrar libro + ¡Se eliminarán todas las cuentas y transacciones en este libro! + Borrar el libro + Última exportación: + Habilitar sincronización + Nuevo libro + La transacción seleccionada tiene ningún desglose y no se puede abrir + %1$d desglose + en %1$s - %d account - %d accounts + %d cuenta + %d cuentas - %d transaction - %d transactions + %d transacción + %d transacciones - EXPENSE - INCOME + GASTO + INGRESO - Connected to Google Drive - Unable to connect to Google Drive - Please enter an amount to split - external service - Updated transaction recurring schedule - Since - All time - Recommend in Play Store - until %1$s - on %1$s - for %1$s times - Compact View + Conectado a Google Drive + No se puede conectar a Google Drive + Por favor ingrese una cantidad para dividir + servicio externo + Calendario de transacciones recurrentes actualizado + Desde + Todos los tiempos + Recomendar en Play Store + hasta %1$s + en %1$s + %1$s veces + Vista compacta Libro %1$d + never diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index 3497cb807..9b2ac3ea0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -21,6 +21,7 @@ Información Exportar OFX Añadir una nueva transacción a una cuenta + View account details No hay cuentas que mostrar Nombre de la cuenta Cancelar @@ -63,7 +64,7 @@ Ajustes Tarjeta SD - DropBox + Dropbox Google Drive ownCloud Enviar a… @@ -85,6 +86,7 @@ Registrar transacciones en GnuCash Crear cuentas en GnuCash Mostrar cuentas + Hide account balance in widget Crear Cuentas Seleccionar cuentas a crear No hay cuentas en Gnucash.\nCree una cuenta antes de añadir un widget @@ -204,7 +206,7 @@ Color y tipo de cuenta Borrar sub-cuentas - Reciente + Recientes Favoritos Todas Crea una estructura por defecto de cuentas GnuCash comúnmente usadas @@ -473,4 +475,5 @@ Este proceso solo recoge información que no permite identificar al usuario%1$s veces
Vista compacta Libro %1$d + never diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index 07e296b45..8f1958fea 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -21,6 +21,7 @@ Tiedot Vie… Lisää uusi tapahtuma tilille + View account details Ei näytettävissä olevia tilejä Tilin nimi Peruuta @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -478,4 +480,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index a264ad7a1..e4115c88f 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -21,6 +21,7 @@ Informations Exporter en OFX Ajoute une nouvelle transaction à un compte + View account details Aucun compte à afficher Nom du compte Annuler @@ -28,8 +29,8 @@ Test Entrer code Mauvais code, veuillez réessayer - Code ajouté - Veuillez confirmer vorte code + Code d\'entrée ajouté + Veuillez confirmer votre code Code de confirmation invalide. Veuillez réessayer Description Montant @@ -48,22 +49,22 @@ Confirmer la suppression Toutes les transactions dans ce compte seront aussi supprimées Éditer la transaction - Note + Ajouter note DÉPLACER %1$d sélectionné(s) Solde: Exporter vers: Exporter les transactions Exporter toutes les transactions - Par défaut, seul les nouvelles transactions depuis le dernier export seront exportées. Cochez cette option pour exporter toutes les transactions + Par défaut, seules les nouvelles transactions depuis le dernier export seront exportées. Cochez cette option pour exporter toutes les transactions Erreur lors de l\'export des données en %1$s Exporter - Effacer les transactions apres export - Toutes les transactions exportées seront supprimées aprés l\'export + Effacer les transactions après export + Toutes les transactions exportées seront supprimées après l\'export Paramètres Carte SD - DropBox + Dropbox Google Drive ownCloud Envoyer vers… @@ -71,39 +72,40 @@ Déplacer Déplacer %1$d transaction(s) Compte de destination - Accés carte SD + Accéder à la carte SD Impossible de déplacer les transactions.\nLe compte de destination utilise une monnaie différente du compte d\'origine Général À propos Choisisez une monnaie par défaut Monnaie par défaut - Monnaie par défaut à assignée aux nouveau comptes - Permettre l\'enregistrement des transactions dans GnuCash pour Android - Permettre la création de comptes dans GnuCash pour Android + Monnaie par défaut à assignée aux nouveaux comptes + Permet l\'enregistrement des transactions dans GnuCash pour Android + Permet la création de comptes dans GnuCash pour Android Vos données GnuCash Lire et modifier les données GnuCash Enregistrer les transactions dans GnuCash Créer comptes dans GnuCash Afficher le compte + Hide account balance in widget Créer les comptes - Choisisez les comptes à créés - Aucun compte éxistant dans GnuCash.\nCréez un compte avant d\'ajouter un widget + Choisissez les comptes à créer + Aucun compte existant dans GnuCash.\nCréez un compte avant d\'ajouter un widget Version logiciel Licence Apache License v2.0. Cliquez pour plus de détails - Général + Préférences Générales Sélectionner un compte Il n\'existe pas de transaction disponible pour l\'exportation - Code - Préférences code - Code activé - Code désactivé - Changer le code + Code d\'accès + Préférences code d\'accès + Code d\'accès activé + Code d\'accès désactivé + Changer le code d\'accès À propos de GnuCash - A mobile finance management and expense-tracker designed for Android + Une application de gestion financière mobile et de suivi des dépenses conçu pour Android A propos - Fichier %1$s exporté en :\n - GnuCash Android %1$s export + %1$s fichier exporté vers : \n + Exportation GnuCash Android %1$s GnuCash Android export de Transactions Préférences des transactions @@ -121,24 +123,18 @@ Supprimer les transactions exportées Email d\'export par défaut Email par défaut pour les exports. Vous pourrez toujours le changer lors de votre prochain export. - Transfert entre comptes - Toutes les transactions seront transférées d\'un compte à l\'autre - Activer les doubles entrée + Transfert de compte + Toutes les transactions seront un transfert d’un compte à un autre + Activer la Double entrée Solde Entrer un nom de compte pour créer un compte Monnaie Compte parent Utiliser l\'entête XML d\'OFX Activez cette option lors d\'un export vers une application tierce autre que GnuCash pour PC - Nouveautées + Nouveautés - - Support for multiple different books \n - - Adds ownCloud as destination for exports\n - - Compact view for transactions list\n - - Re-design of passcode lock screen\n - - Improved handling of scheduled transactions\n - - Multiple bug fixes and improvements\n - +-Support pour plusieurs livres comptables différents\n - Ajoute ownCloud comme destination pour les exportations\n - Vue compacte pour la liste de transactions\n - Nouvelle implémentation de l\'écran de verrouillage\n - Traitement amélioré des transactions programmées\n - Plusieurs corrections de bugs et améliorations\n
Passer Entrez un montant pour sauvegarder la transaction Les transactions multi-devises ne peuvent pas être modifiées @@ -146,9 +142,9 @@ Import de comptes Une erreur s\'est produite pendant l\'import de vos comptes GnuCash Comptes GnuCash importés avec succès - Importe l\'organisation d\'un compte exporté depuis GnuCash pour PC - Importer des comptes GnuCash - Supprimer tous les comptes dans la base de données. Toutes les transactions seront également supprimés. + Importer la structure de compte exporté de GnuCash pour Bureau + Import XML GnuCash + Supprimer tous les comptes dans la base de données. Toutes les transactions seront également supprimées. Supprimer tous les comptes Comptes Tous les comptes ont été supprimés avec succès @@ -191,7 +187,7 @@ DEVISES ACTIONS FONDS COMMUNS - TRADING + COMMERCE QIF @@ -209,27 +205,25 @@ Tous Crée une structure de compte GnuCash par défaut couramment utilisé Crée comptes par défaut - A new book will be opened with the default accounts\n\nYour current accounts and transactions will not be modified! + Un nouveau livre sera ouvert avec les comptes courants par défaut\n\n Vos comptes et opérations actuels ne seront pas modifiés ! Transactions planifiées - Bienvenue sur GnuCash Android!\nVous pouvez soit créer - une hiérarchie de comptes couramment utilisés, importer votre propre structure de compte GnuCash.\n\nLes deux options sont également - disponibles dans les paramètres de l\'application de sorte que vous puissiez décider plus tard. + Bienvenue à GnuCash Android ! \nVous pouvez soit créer une hiérarchie de comptes couramment utilisés, soit importer votre propre structure de compte GnuCash. \n\nLes deux options sont également disponibles dans les paramètres de l’application afin que vous puissiez décider plus tard. Transactions planifiées Selectionnez une destination pour l\'export Memo - Dépense - Reçu + Dépenser + Recevoir Retrait Dépôt Paiement - Charge + Frais Diminuer Augmenter Revenu Remboursement Frais - Note - Facture + Facture + Facture d\'achat Achat Vente Répétitions @@ -241,26 +235,26 @@ Enregistrer les soldes des comptes d\'ouverture OFX ne support pas les transactions à double entrée Génère un fichier QIF par monnaies - Scissions de transaction + Transactions séparées Déséquilibre : Ajouter scission Favori Panneau de navigation ouvert Panneau de navigation fermé Rapports - Diagramme Circulaire + Graphique en camembert Graphique linéaire Histogramme - Préférences Rapport + Préférences de Rapport Sélectionnez la monnaie Couleur du compte dans les rapports Utiliser la couleur du compte dans le diagramme bandes/circulaire Rapports Tri par taille - Show legend - Show labels + Afficher la légende + Afficher les libellés Montrer pourcentage - Show average lines + Afficher les lignes moyennes Groupe par petites tranches Aucune données de graphe disponible Global @@ -304,18 +298,18 @@ ownCloud https:// Serveur OC inaccessible - OC username/password invalid - Invalid chars: \\ < > : \" | * ? - OC server OK - OC username/password OK - Dir name OK + Nom d’utilisateur/mot de passe OC non valide + Caractères non valides : \\ < > : \" | * ? + Serveur OC OK + Nom d’utilisateur/mot de passe OC OK + Nom Répertoire OK - Journalier + Quotidien Tous les %d jours Hebdomadaire - Tous les %d semaines + Toutes les %d semaines Mensuel @@ -326,13 +320,11 @@ Tous les %d ans Activer le rapport de crash - Activer pour envoyer aux développeurs d\'amélioration des informations sur les dysfonctionnements (recommandé). -Aucune information permettant d\'identifier l\'utilisateur ne sera recueillis dans le cadre de ce processus! - + Envoyer automatiquement les informations de dysfonctionnement de l’app aux développeurs. Aucune information permettant d\'identifier l\'utilisateur ne sera recueillie dans le cadre de ce processus! Format - Le répertoire de sauvegarde non trouvé. Vérifiez la carte SD ! + Répertoire de sauvegarde non trouvé. Vérifiez la carte SD ! Entrez votre ancien mot de passe - Entrez votre nouveau code + Entrez votre nouveau mot de passe Exports planifiés Exports planifiés Pas d\'exports planifiés à afficher @@ -344,13 +336,13 @@ Aucune information permettant d\'identifier l\'utilisateur ne sera recueillis da Aucun comptes favoris Actions prévues "Fini, dernière exécution le " - Select a bar to view details + Sélectionnez une barre pour afficher les détails Suivant Terminer Monnaie par défaut Configuration du Compte Sélectionner Monnaie - Feedback Options + Options des commentaires Créer des comptes par défaut Importer mes comptes Me laisser gérer @@ -375,14 +367,14 @@ Aucune information permettant d\'identifier l\'utilisateur ne sera recueillis da Vers: Fournissez le montant converti ou le taux de change pour transférer des fonds Taux de change - Fetch quote + Récupérer Citation Montant converti Feuille Dépenses des 3 derniers mois Actifs Total Dettes Total Valeur Nette - Assets + Actifs Dettes Capitaux propres @@ -393,21 +385,21 @@ Aucune information permettant d\'identifier l\'utilisateur ne sera recueillis da Année Bilans Total: - Google+ Community - Translate GnuCash - Share ideas, discuss changes or report problems - Translate or proof-read on CrowdIn - No compatible apps to receive the exported transactions! - Move… - Duplicate + Communauté Google + + Traduire GnuCash + Partager des idées, discuter des changements ou signaler des problèmes + Traduire ou relire sur CrowdIn + Aucune application compatible pour recevoir les transactions exportées ! + Déplacer… + Dupliquer Budgets - Cash Flow + Flux de trésorerie Budgets - Enable compact view - Enable to always use compact view for transactions list - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s - Invalid amount + Activez le mode compact + Activez pour toujours utiliser la vue compacte pour la liste des opérations + Taux de change non valide + par exemple 1 %1$s = x.xx %2$s + Montant non valide Mois actuel 3 derniers mois @@ -438,41 +430,42 @@ Aucune information permettant d\'identifier l\'utilisateur ne sera recueillis da WXYZ 0 + - Manage Books - Manage Books… - Select any part of the chart to view details - Confirm delete Book - All accounts and transactions in this book will be deleted! - Delete Book - Last Exported: - Enable Sync - New Book - The selected transaction has no splits and cannot be opened - %1$d splits - in %1$s + Gérer les livres + Gérer les livres… + Sélectionnez une partie du graphique pour afficher les détails + Confirmer la suppression du livre + Tous les comptes et transactions dans ce livre seront supprimées ! + Supprimer le livre + Dernières exportations : + Activer la synchronisation + Nouveau livre + La transaction sélectionnée n’a aucun mouvement et ne peut pas être ouvert + %1$d mouvements + dans %1$s - %d account - %d accounts + %d compte + %d comptes %d transaction %d transactions - EXPENSE - INCOME + FRAIS + REVENU - Connected to Google Drive - Unable to connect to Google Drive - Please enter an amount to split - external service - Updated transaction recurring schedule - Since - All time - Recommend in Play Store - until %1$s - on %1$s - for %1$s times - Compact View - Book %1$d + Connecté à Google Drive + Impossible de se connecter à Google Drive + Veuillez entrer un montant à diviser + services externe + Calendrier de mise à jour de transaction récurrente + Depuis le + Tous les temps + Recommander dans le PlayStore + jusqu\'à %1$s + sur %1$s + pour la %1$s fois + Vue compacte + Livre %1$d + never diff --git a/app/src/main/res/values-hu-rHU/strings.xml b/app/src/main/res/values-hu-rHU/strings.xml index fc8c18ac5..a0ac4bac5 100644 --- a/app/src/main/res/values-hu-rHU/strings.xml +++ b/app/src/main/res/values-hu-rHU/strings.xml @@ -21,6 +21,7 @@ Információ Export OFX Új tranzakció hozzáadása egy fiókhoz + View account details Nincs megjeleníthető fiók Fiók neve Mégsem @@ -63,7 +64,7 @@ Beállítások SD-kártya - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -480,4 +482,5 @@ No user-identifiable information will be collected as part of this process! for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-in-rID/strings.xml b/app/src/main/res/values-in-rID/strings.xml index 1df061e4a..9322411bd 100644 --- a/app/src/main/res/values-in-rID/strings.xml +++ b/app/src/main/res/values-in-rID/strings.xml @@ -16,159 +16,159 @@ limitations under the License. --> - Create Account - Edit Account + Buat Akun + Ubah Akun Info - Export… - Add a new transaction to an account - No accounts to display - Account name - Cancel - Save - Test - Enter Passcode - Wrong passcode, please try again - Passcode set - Please confirm your passcode - Invalid passcode confirmation. Please try again - Description - Amount - New transaction - No transactions to display - DATE & TIME - Account + Ekspor… + Tambah transaksi baru ke akun + Lihat rincian akun + Tidak ada akun untuk ditampilkan + Nama akun + Batal + Simpan + Tes + Masukkan Kode akses + Kode akses salah, silakan coba lagi + Kode akses dibuat + Harap konfirmasi kode akses Anda + Konfirmasi kode akses tidak valid. Silakan cobalagi + Deskripsi + Jumlah + Transaksi baru + Tidak ada transaksi untuk ditampilkan + TANGGAL & WAKTU + Akun DEBIT - CREDIT - Accounts - Transactions - Delete - Delete - Cancel - Account deleted - Confirm delete - All transactions in this account will also be deleted - Edit Transaction - Add note - MOVE - %1$d selected - Balance: - Export To: - Export Transactions - Export all transactions - By default, only new transactions since last export will be exported. Check this option to export all transactions - Error exporting %1$s file - Export - Delete transactions after export - All exported transactions will be deleted when exporting is completed - Settings + KREDIT + Akun + Transaksi + Hapus + Hapus + Batal + Akun dihapus + Konfirmasi penghapusan + Semua transaksi dalam akun ini juga akan dihapus + Ubah Transaksi + Tambah catatan + PINDAHKAN + %1$d dipilih + Saldo: + Ekspor ke: + Ekspor Transaksi + Ekspor semua transaksi + Secara default, hanya transaksi baru sejak ekspor terakhir yang akan diekspor. Beri centang pilihan ini untuk mengekspor semua transaksi + Kesalahan mengekspor file %1$s + Ekspor + Hapus transaksi setelah mengekspor + Semua transaksi yang diekspor akan dihapus saat proses ekspor selesai + Pengaturan SD Card - DropBox + Dropbox Google Drive ownCloud - Send to… + Kirim ke… - Move - Move %1$d transaction(s) - Destination Account - Access SD Card - Cannot move transactions.\nThe destination account uses a different currency from origin account - General - About - Choose default currency - Default currency - Default currency to assign to new accounts - Enables recording transactions in GnuCash for Android - Enables creation of accounts in GnuCash for Android - Your GnuCash data - Read and modify GnuCash data - Record transactions in GnuCash - Create accounts in GnuCash - Display account - Create Accounts - Select accounts to create - No accounts exist in GnuCash.\nCreate an account before adding a widget + Pindahkan + Memindah transaksi %1$d + Akun Tujuan + Akses SD Card + Tidak bisa memindah transaksi. \n Akun tujuan menggunakan mata uang yang berbeda dengan akun asal + Umum + Tentang + Pilih mata uang default + Mata uang default + Mata uang default untuk ditetapkan ke akun baru + Memungkinkan mencatat transaksi di GnuCash untum Android + Memungkinkan membuat akun di GnuCash untuk Android + Data GnuCash Anda + Membaca dan memodifikasi data GnuCash + Mencatat transaksi di GnuCash + Membuat akun di GnuCash + Tampilan akun + Sembunyikan saldo akun dalam widget + Buat akun + Pilih akun untuk dibuat + Tidak ada akun di GnuCash.\nBuat sebuah akun sebelum menambahkan sebuah widget Build version - License - Apache License v2.0. Click for details - General Preferences - Select Account - There are no transactions available to export - Passcode - Passcode Preferences - Passcode Turned On - Passcode Turned Off - Change Passcode - About GnuCash - A mobile finance management and expense-tracker designed for Android - About - %1$s file exported to:\n - GnuCash Android %1$s export - GnuCash Android Export from - Transactions - Transaction Preferences - Account Preferences - Default Transaction Type - The type of transaction to use by default, CREDIT or DEBIT + Lisensi + Lisensi Apache v2.0. Klik untuk rincian + Preferensi umum + Pilih akun + Tidak ada transaksi yang tersedia untuk diekspor + Kode akses + Pengaturan Kode Akses + Kode Akses Diaktifkan + Kode Akses Dimatikan + Ganti Kode Akses + Tentang GnuCash + Sebuah manajemen finansial mobile dan pelacak pengeluaran yang dibuat untuk Android + Tentang + %1$s file diekspor ke:\n + GnuCash Android %1$s ekspor + GnuCash Android Ekspor dari + Transaksi + Preferensi Transaksi + Preferensi Akun + Tipe Transaksi Default + Tipe transaksi untuk digunakan secara default, KREDIT atau DEBET - CREDIT + KREDIT DEBIT - Are you sure you want to delete ALL transactions? - Are you sure you want to delete this transaction? - Export - Export all transactions - Delete exported transactions - Default export email - The default email address to send exports to. You can still change this when you export. - Transfer Account - All transactions will be a transfer from one account to another - Activate Double Entry - Balance - Enter an account name to create an account - Currency - Parent account - Use XML OFX header - Enable this option when exporting to third-party application other than GnuCash for desktop - What\'s New + Apakah Anda yakin Anda ingin menghapus SEMUA transaksi? + Apakah Anda yakin ingin menghapus transaksi ini? + Ekspor + Ekspor semua transaksi + Hapus transaksi yang diekspor + Email ekspor default + Alamat email default untuk mengirim ekspor. Anda tetap dapat mengubahnya saat Anda melakukan ekspor. + Akun Transfer + Seluruh transaksi akan menjadi sebuah transfer dari satu akun ke yang lainnya + Aktifkan Double Entry + Saldo + Tuliskan nama akun untuk membuat sebuah akun + Mata Uang + Akun induk + Gunakan header XML OFX + Aktifkan opsi ini ketika mengekspor ke aplikasi pihak ketiga selain GnuCash versi desktop + Yang Terbaru - - Support for multiple different books \n - - Adds ownCloud as destination for exports\n - - Compact view for transactions list\n - - Re-design of passcode lock screen\n - - Improved handling of scheduled transactions\n - - Multiple bug fixes and improvements\n + - Mendukung lebih dari satu buku yang berbeda \n + - Menambahkan ownCloud sebagai tujuan untuk ekspor\n + - Tampilan yang terpadu untuk daftar transaksi\n + - Desain ulang terkait layar kunci kode akses\n + - Penanganan yang ditingkatkan terkait transaksi terjadwal\n + - Perbaikan berbagai bug dan beberapa peningkatan\n - Dismiss - Enter an amount to save the transaction - Multi-currency transactions cannot be modified - Import GnuCash Accounts - Import Accounts - An error occurred while importing the GnuCash accounts - GnuCash Accounts successfully imported - Import account structure exported from GnuCash desktop - Import GnuCash XML - Delete all accounts in the database. All transactions will be deleted as - well. + Abaikan + Tuliskan jumlah untuk menyimpan transaksi + Transaksi multi-mata-uang tidak dapat dimodifikasi + Impor Akum GnuCash + Impor Akun + Terjadi error saat mengimpor akun GnuCash + Akun GnuCash berhasil diimpor + Mengimpor struktur akun yang telah diekspor dari GnuCash desktop + Impor XML GnuCash + Hapus seluruh akun dalam database. Seluruh transaksi akan dihapus + juga. - Delete all accounts - Accounts - All accounts have been successfully deleted - Are you sure you want to delete all accounts and transactions?\n\nThis - operation cannot be undone! - - Account Type - All transactions in all accounts will be deleted! - Delete all transactions - All transactions successfully deleted! - Importing accounts - Tap again to confirm. ALL entries will be deleted!! - Transactions - Sub-Accounts - Search - Default Export Format - File format to use by default when exporting transactions - Export transactions… + Hapus seluruh akun + Akun + Semua akun telah berhasil dihapus + Apakah Anda yakin Anda ingin menghapus seluruh akun dan transaksi? \n\nOperasi ini tidak dapat dibatalkan! + Jenis Akun + Seluruh transaksi di semua akun akan dihapus! + Hapus seluruh transaksi + Seluruh transaksi berhasil dihapus! + Mengimpor akun + Tap lagi untuk konfirmasi. SELURUH entri akan dihapus!! + Transaksi + Sub-Akun + Cari + Formart Ekspor Default + Format file untuk digunakan secara default ketika mengekspor transaksi + Ekspor transaksi… Recurrence Imbalance @@ -221,25 +221,25 @@ Transactions Select destination for export Memo - Spend - Receive - Withdrawal - Deposit - Payment - Charge - Decrease - Increase - Income + Mengeluarkan + Menerima + Penarikan + Setor + Pembayaran + Biaya + Mengurangi + Menambahkan + Pendapatan Rebate - Expense - Bill + Pengeluaran + Tagihan Invoice - Buy - Sell - Repeats - No recent backup found - Opening Balances - Equity + Beli + Jual + Mengulangi + Tidak ada cadangan terbaru + Saldo Awal + Ekuitas Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances @@ -471,4 +471,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 85e3fb2d4..ba8f3c99b 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -21,6 +21,7 @@ Informazioni Esporta… Aggiungi una nuova transazione al conto + Visualizza i dettagli dell\'account Nessun conto da visualizzare Nome conto Annulla @@ -85,6 +86,7 @@ Registra le transazioni in GnuCash Crea conti in GnuCash Visualizza conto + Nascondi il saldo del conto nel widget Crea conti Selezione dei conti da creare Non esiste alcun conto in GnuCash.\nCreare un conto prima di aggiungere il widget @@ -475,4 +477,5 @@ per %1$s volte Visualizzazione compatta Libro %1$d + mai diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index c6ab81738..4d38e6933 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -21,6 +21,7 @@ פרטים ייצוא… הוספת העברה כספים לחשבון + View account details אין חשבונות לתצוגה שם חשבון ביטול @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud שלח אל… @@ -85,6 +86,7 @@ שמור העברות בGnuCash צור חשבונות ב GnuCash הצג חשבון + Hide account balance in widget צור חשבונות בחר חשבונות ליצור לא קיימים חשבונות ב- GnuCassh.\n צור חשבון לפני הוספת widget @@ -492,4 +494,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index d4ea955d3..e2108f9ed 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -21,6 +21,7 @@ 情報 エクスポート… 新規の取引を入力 + View account details 表示する勘定科目がありません 勘定科目名 キャンセル @@ -85,6 +86,7 @@ GnuCashで取引を記録する GnuCashで費目を新規登録する 勘定科目を表示 + Hide account balance in widget 勘定科目を作成 作成する勘定科目を選択 GnuCashに勘定科目が存在しません。\nウィジェットを追加する前に勘定科目を作成してください @@ -464,4 +466,5 @@ %1$s 回 コンパクト表示 帳簿 %1$d + never diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index da71a40d7..c74d826dd 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -21,6 +21,7 @@ 정보 내보내기... 계정에 새 거래 추가 + View account details 계정 없음 계정 이름 취소 @@ -63,7 +64,7 @@ 설정 SD 카드 - DropBox + Dropbox Google Drive ownCloud 보낼 곳 지정... @@ -85,6 +86,7 @@ GnuCash에서 거래를 기록 GnuCash에서 계정 만들기 계정 표시 + Hide account balance in widget 계정 만들기 만들 계정을 선택합니다 GnuCash에 계정이 없습니다.\n위젯을 만들기 전에 계정을 생성하십시오 @@ -465,4 +467,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-lv-rLV/strings.xml b/app/src/main/res/values-lv-rLV/strings.xml index 0f691ac06..14e900f06 100644 --- a/app/src/main/res/values-lv-rLV/strings.xml +++ b/app/src/main/res/values-lv-rLV/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -485,4 +487,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-nb/strings.xml b/app/src/main/res/values-nb/strings.xml index 074973927..7592d7d06 100644 --- a/app/src/main/res/values-nb/strings.xml +++ b/app/src/main/res/values-nb/strings.xml @@ -21,6 +21,7 @@ Informasjon Eksport... Legge til en ny transaksjon i en konto + View account details Ingen kontoer for å vise Kontonavn Avbryt @@ -63,7 +64,7 @@ Innstillinger SD-kort - DropBox + Dropbox Google Disk ownCloud Send til… @@ -85,6 +86,7 @@ Registrere transaksjoner i GnuCash Opprette kontoer i GnuCash Vis konto + Hide account balance in widget Opprett konto Velg kontoer å opprette Det finnes ingen kontoer i GnuCash.\nOpprett en konto før du legger til en widget @@ -393,12 +395,12 @@ Dele ideer, diskutere endringer eller rapportere problemer Oversette eller korrekturles på CrowdIn Ingen kompatible apper til å motta de eksporterte transaksjonene! - Move… - Duplicate - Budgets + Flytt… + Dupliser + Budsjetter Kontantstrøm - Budgets - Enable compact view + Budsjetter + Aktiver Kompaktvisning Enable to always use compact view for transactions list Ugyldig valutakurs e.g. 1 %1$s = x.xx %2$s @@ -470,4 +472,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-nl-rNL/strings.xml b/app/src/main/res/values-nl-rNL/strings.xml index 734ca4e5a..ee39a7cd7 100644 --- a/app/src/main/res/values-nl-rNL/strings.xml +++ b/app/src/main/res/values-nl-rNL/strings.xml @@ -21,6 +21,7 @@ Info OFX exporteren Nieuwe boeking op een rekening + View account details Geen rekeningen beschikbaar Rekeningnaam Annuleren @@ -85,6 +86,7 @@ Boekingen opslaan in GnuCash Rekeningen aanmaken in GnuCash Rekening tonen + Hide account balance in widget Rekeningen aanmaken Standaard rekeningen selecteren Geen rekeningen beschikbaar.\nU moet een rekening aanmaken alvorens een widget toe te voegen @@ -479,4 +481,5 @@ No user-identifiable information will be collected as part of this process! for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-no-rNO/strings.xml b/app/src/main/res/values-no-rNO/strings.xml index 362ea0f37..cd524823f 100644 --- a/app/src/main/res/values-no-rNO/strings.xml +++ b/app/src/main/res/values-no-rNO/strings.xml @@ -21,6 +21,7 @@ Informasjon Eksport... Legge til en ny transaksjon i en konto + View account details Ingen kontoer for å vise Kontonavn Avbryt @@ -63,7 +64,7 @@ Innstillinger SD-kort - DropBox + Dropbox Google Disk ownCloud Send til… @@ -85,6 +86,7 @@ Registrere transaksjoner i GnuCash Opprette kontoer i GnuCash Vis konto + Hide account balance in widget Opprett konto Velg kontoer å opprette Det finnes ingen kontoer i GnuCash.\nOpprett en konto før du legger til en widget @@ -470,4 +472,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index e80d09ded..304697c88 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -21,6 +21,7 @@ Info Eksportuj… Dodaj nową transakcję do konta + View account details Brak kont do wyświetlenia Nazwa konta Anuluj @@ -63,7 +64,7 @@ Ustawienia Karta SD - DropBox + Dropbox Dysk Google ownCloud Send to… @@ -86,6 +87,7 @@ Konto docelowe używa innej waluty niż konto wyjściowe
Rejestrować transakcje w GnuCash Tworzyć konta w GnuCash Wyświetl konto + Hide account balance in widget Utwórz konta Wybierz konta do utworzenia Brak kont w GnuCash.\nUtwórz konto zanim dodasz widżet @@ -479,4 +481,5 @@ Konto docelowe używa innej waluty niż konto wyjściowe for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index f3b7b3965..9d5c5a728 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -21,6 +21,7 @@ Informação Exportar Adicionar nova transação a uma conta + View account details Sem contas para mostrar Nome da Conta Cancelar @@ -63,7 +64,7 @@ Configurações Cartão SD - DropBox + Dropbox Google Drive ownCloud Enviar para… @@ -85,6 +86,7 @@ Gravar transações no GnuCash Criar contas no GnuCash Mostrar conta + Hide account balance in widget Criar Contas Escolha as contas a criar Não existem contas no GnuCash.\nCrie uma conta antes de adicionar um widget @@ -132,13 +134,12 @@ Active esta opção quando fizer exportações para outras aplicações que não seja o GnuCash para Desktop O que há de novo - - Support for multiple different books \n - - Adds ownCloud as destination for exports\n - - Compact view for transactions list\n - - Re-design of passcode lock screen\n - - Improved handling of scheduled transactions\n - - Multiple bug fixes and improvements\n - +- Suporte para vários livres diferentes\n +- Adiciona o ownCloud como destino das exportações\n +- Vista compacta da lista das transações\n +- Redesenhado o ecrã de bloqueio de password\n +- Melhorado o tratamento de transações agendadas\n + - Várias correcções de erros e melhoramentos\n Descartar Introduza um valor para gravar a transação As transações multi-moeda não podem ser alteradas @@ -209,7 +210,7 @@ Todas Cria uma estrutura de contas GnuCash padrão Cria contas padrão - A new book will be opened with the default accounts\n\nYour current accounts and transactions will not be modified! + Irá ser aberto um novo livro com as contas por defeito\n\nAs suas contas e transações não irão ser modificadas! Transações agendadas Bem vindo ao GnuCash Android! \nPode criar um hierarquia de contas, ou importar a sua estrutura de contas do GnuCash. \n\n Ambas as opções estão disponíves bas Opções da aplicação, para que possa decidir mais tarde. @@ -417,7 +418,7 @@ Neste processo não serão recolhidas informações do utilizador! 1 - + 2 ABC 3 @@ -437,14 +438,14 @@ Neste processo não serão recolhidas informações do utilizador! 0 + Gerenciar livros - Manage Books… + Gerir Livros… Selecione qualquer parte do gráfico para ver os detalhes - Confirm delete Book + Confirme o apagar do Livro Todas as contas e transações neste livro serão excluídas! Apagar livro Última exportação: Ativar a Sincronização - New Book + Novo Livro A transação selecionada não tem divisões e não pode ser aberta %1$d divisões em %1$s @@ -462,15 +463,16 @@ Neste processo não serão recolhidas informações do utilizador! Conectado ao Google Drive Impossível conectar ao Google Drive - Please enter an amount to split + Por favor introduza um montante a dividir serviço externo Agenda recorrente de transação atualizada Desde Desde o início Recomendado na Play Store até %1$s - on %1$s + na %1$s por %1$s vezes Visualização compacta - Book %1$d + Livro %1$d + never diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 394812e63..0fa912396 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -21,6 +21,7 @@ Informação Exportar Adicionar nova transacção a uma conta + View account details Sem contas para mostrar Nome da conta Cancelar @@ -63,7 +64,7 @@ Configurações Cartão SD - DropBox + Dropbox Google Drive ownCloud Enviar para… @@ -85,6 +86,7 @@ Gravar transacções no GnuCash Criar contas no GnuCash Mostrar conta + Hide account balance in widget Criar contas Escolha as contas a criar Não existem contas no GnuCash.\nCrie uma conta antes de adicionar um widget @@ -472,4 +474,5 @@ Neste processo não serão recolhidas informações do utilizador! para %1$s vezes Vista Compacta Livro %1$d + never diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index 9c9c4d03e..25f76e24c 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -21,6 +21,7 @@ Info Export… Adăugaţi o nouă tranzacţie într-un cont + View account details Nu există conturi pentru a afișa Numele contului Rezilia @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -485,4 +487,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 1d76ac7ae..3c22f7b47 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -21,6 +21,7 @@ Информация Экспорт… Новая проводка + View account details Нет счетов Имя счёта Отмена @@ -63,7 +64,7 @@ Настройки Карта памяти - DropBox + Dropbox Google Диск ownCloud Отправить… @@ -85,6 +86,7 @@ Запись проводок в GnuCash Создайте учетные записи в GnuCash Показать счёт + Hide account balance in widget Создать счета Выберите счета для создания Нет счетов в Gnucash.\nСначала создайте счета, а потом добавляйте виджет. @@ -482,4 +484,5 @@ для %1$s раз Компактный вид Книга %1$d + never diff --git a/app/src/main/res/values-sr-rSP/strings.xml b/app/src/main/res/values-sr-rSP/strings.xml index 1d8a2d7a0..3ff688a13 100644 --- a/app/src/main/res/values-sr-rSP/strings.xml +++ b/app/src/main/res/values-sr-rSP/strings.xml @@ -21,6 +21,7 @@ Инфо Извоз… Додајте нову трансакцију на рачун + View account details Нема рачуна за приказ Назив рачуна Откажи @@ -63,7 +64,7 @@ Подешавања SD Картица - DropBox + Dropbox Google диск ownCloud Send to… @@ -85,6 +86,7 @@ Сними трансакције у GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -485,4 +487,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index 892de105d..5ef6762b3 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -21,6 +21,7 @@ Information Exportera… Lägg till en transaktion till ett konto + View account details Det finns inga konton att visa Kontonamn Avbryt @@ -54,27 +55,27 @@ Saldo: Exportera till: Exportera transaktioner - Export all transactions - By default, only new transactions since last export will be exported. Check this option to export all transactions - Error exporting %1$s file - Export - Delete transactions after export - All exported transactions will be deleted when exporting is completed - Settings + Exportera alla transaktioner + Som standard exporteras endast nya transaktioner sedan senaste export. Markera detta alternativ för att exportera alla transaktioner + Fel uppstod då filen skulle %1$s exporteras + Exportera + Radera transaktioner efter export + Alla exporterade transaktioner raderas när exporten har slutförs + Inställningar - SD Card - DropBox + SD-kort + Dropbox Google Drive ownCloud - Send to… + Skicka till… - Move - Move %1$d transaction(s) + Flytta + Flytta %1$d transaktion(er) Destination Account Access SD Card Cannot move transactions.\nThe destination account uses a different currency from origin account - General - About + Allmänt + Om Choose default currency Default currency Default currency to assign to new accounts @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -478,4 +480,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-tr-rTR/strings.xml b/app/src/main/res/values-tr-rTR/strings.xml index 918ccb525..96b87cdef 100644 --- a/app/src/main/res/values-tr-rTR/strings.xml +++ b/app/src/main/res/values-tr-rTR/strings.xml @@ -21,6 +21,7 @@ Bilgilendirme Dışarı Aktar… Bir hesaba yeni bir işlem ekle + View account details No accounts to display Hesap adı İptal @@ -63,7 +64,7 @@ Ayarlar Hafıza Kartı - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Hesap Oluştur Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -478,4 +480,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-uk-rUA/strings.xml b/app/src/main/res/values-uk-rUA/strings.xml index 9e28f0e0b..600526a2b 100644 --- a/app/src/main/res/values-uk-rUA/strings.xml +++ b/app/src/main/res/values-uk-rUA/strings.xml @@ -21,6 +21,7 @@ Інформація Експортувати OFX Додати до рахунку нову транзакцію + View account details Немає рахунків Ім\'я рахунку Скасувати @@ -63,7 +64,7 @@ Налаштування Карта пам\'яті - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Запис операції в GnuCash Створення рахунків в GnuCash Показати рахунок + Hide account balance in widget Створити рахунки Оберіть рахунки для створення Немає рахунків в Gnucash.\nСтворіть рахунки перед додаваням віджета. @@ -481,4 +483,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index 1df061e4a..8babcdfdd 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget @@ -471,4 +473,5 @@ for %1$s times Compact View Book %1$d + never diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 66b15cc70..a5b97a905 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -17,11 +17,12 @@ --> 创建科目 - 修改科目 + 编辑科目 信息 导出... 为科目增加交易 - 没有要显示的科目 + View account details + 没有可以显示的科目 科目名称 取消 保存 @@ -33,8 +34,8 @@ 密码不一致,请重试 描述 金额 - 新交易 - 没有要显示的交易 + 新建交易 + 没有可以显示的交易 日期时间 科目 借方 @@ -46,30 +47,30 @@ 取消 科目已删除 确认删除 - 科目中的交易同时会被删除 + 本科目中的所有交易会同时被删除 修改交易 备注 移动 - %1$d 已选中 - 合计: + 已选中 %1$d 项 + 科目余额: 导出到: - 导出交易资料 + 导出交易 导出所有交易 默认情况下,自上次导出后新增的交易才会被导出。选择此项后所有的交易都会被导出。 导出%1$s发生错误 导出 导出后删除交易 - 导出完成后现存所有交易都会被删除 + 导出完成后被导出的所有交易都会被删除 设置 SD卡 - DropBox + Dropbox Google 云端硬盘 ownCloud 发送到... 移动 - 移动 %1$d 交易 + 移动 %1$d 笔交易 目的科目 访问 SD Card 不能移动交易。\n两个科目的货币设置不一样。 @@ -85,6 +86,7 @@ 记录交易 创建科目 显示科目 + Hide account balance in widget 创建科目 选择要创建的科目 GnuCash里还没有科目信息。\n使用小部件前需要添加科目 @@ -97,13 +99,13 @@ 密码 密码设置 已开启密码保护 - 没有设置密码 + 已关闭密码保护 修改密码 关于GnuCash Android版财务管理软件 关于 - %1$s文件保存到:\n - GnuCash Android %1$s 的导出文件 + %1$s文件导出到:\n + GnuCash Android %1$s 导出 GnuCash 导出的数据 交易 交易设置 @@ -120,11 +122,11 @@ 导出所有交易 删除已导出的交易 Email设置 - 默认发送导出的OFX文件到这个email地址,当然在导出过程时你仍然可以临时变更。 - 过户帐 - 所有交易会显示成两行,复式簿记 - 使用双行模式 - 帐户余额 + 默认发送导出的文件到这个E-mail地址,当然在导出时仍然可以变更。 + 交易科目 + 所有交易会记录为由一个科目到另一个科目的资金流动 + 使用复式记账法 + 科目余额 需要输入科目名称 货币 上级科目 @@ -133,8 +135,8 @@ 新功能 - 支持多个账簿 \n -- 支持ownCloud\n -- 紧凑列表视图\n +- 支持导出至ownCloud\n +- 紧凑的交易列表视图\n - 重新设计的锁屏界面\n - 改进计划交易功能\n - 多个缺陷修复以及性能提升\n @@ -144,10 +146,10 @@ 不支持修改多币种的交易 导入GnuCash科目 导入科目 - 导入 GnuCash 科目中发生错误。 + 导入 GnuCash 科目时发生错误。 GnuCash 科目资料导入完成。 导入从GnuCash桌面版导出的科目设置 - 导入GnuCash科目 + 导入GnuCash XML 删除科目资料的同时其下的交易信息也会被删除。 删除所有科目 @@ -155,28 +157,28 @@ 所有科目都已删除 确定删除所有科目和交易? \n这个操作不能撤销! - 帐户类型 + 科目类型 所有科目的所有的交易信息将被删除! 删除所有交易 所有交易都已删除 导入科目 - 点击再次确认,所有条目都将删除。 + 再次点击确认,所有条目都将删除。 交易 子科目 搜索 默认的导出格式 - 导出交易信息时使用的文件格式。 + 导出交易信息时默认使用的文件格式。 导出交易… 重复 不平衡的 正在导出交易信息 - 没有要显示的计划交易 + 没有可以显示的计划交易 计划交易已删除 - 占位符 + 占位科目 默认的转账科目 - %d 子科目 + %d 个子科目 现金 @@ -206,17 +208,16 @@ 科目颜色和类型 删除子科目 最近的 - 已加星标 + 收藏 所有 创建通用的科目结构 创建默认科目 - 将会创建新的账簿附带默认的科目 -现在这个账簿不会受到影响 + 将会创建带有默认科目的新账簿\n\n现在这个账簿不会受到影响 计划的交易 - 欢迎使用GnuCash Android! \n你可以选择:1)创建常用的科目结构,2)导入自定义的科目结构。\或者稍后再决定,两种选择也能在设置中找到。 + 欢迎使用GnuCash Android! \n你可以选择:1)创建常用的科目结构,2)导入自定义的科目结构。\n\n或者您也可以稍后在设置中进行选择。 - 计划的交易 - 选择存储的位置 + 交易 + 选择导出的目标 描述 花费 收到 @@ -227,9 +228,9 @@ 减少 增加 收入 - 回扣 + 返现 费用 - 支付 + 账单 发票 买入 卖出 @@ -237,7 +238,7 @@ 还没有备份 期初余额 所有者权益 - 当删除所有交易后,还保持曾经的账户余额作为新的期初余额。 + 当删除所有交易后,还保持当前的账户余额作为新的期初余额。 保存账户的期初余额 OFX 格式不支持复式簿记 每种货币都会生成一个QIF文件 @@ -467,4 +468,5 @@ 共%1$s次 紧凑视图 账簿 %1$d + never diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml index 9ceab0277..ea205020f 100644 --- a/app/src/main/res/values-zh-rTW/strings.xml +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -16,183 +16,183 @@ limitations under the License. --> - 创建科目 - 修改科目 - 信息 - 导出OFX - 为科目增加交易 + 新增科目 + 編輯科目 + 資訊 + 匯出OFX + 给科目添加交易 + View account details 没有要显示的科目 - 科目名称 + 科目名稱 取消 - 保存 - Test - 输入密码 - 密码错误,请再试一次 - 密码已设置 - 请再输入一次 - 密码不一致,请重试 + 存檔 + 測試 + 輸入密碼 + 密碼錯誤,請重試一次 + 密碼已設置 + 請再輸入一次 + 密碼不一致,請重試 描述 - 金额 + 金額 新交易 - 没有要显示的交易 - 日期时间 + 没有要顯示的交易 + 日期時間 科目 借方 - 贷方 + 貸方 科目 交易 删除 删除 取消 科目已删除 - 确认删除 - 科目中的交易同时会被删除 - 修改交易 - 备注 - 移动 - %1$d 已选中 - 合计: - Export To: - 导出交易资料 - 导出所有交易 - 默认情况下,自上次导出后新增的交易才会被导出。选择此项后所有的交易都会被导出。 - 导出%1$s发生错误 - 导出 - Delete transactions after export - 导出完成后现存所有交易都会被删除 - 设置 + 確認刪除 + 科目中的交易记录同时会被删除 + 編輯交易 + 備註 + 移動 + %1$d 已選中 + 合計: + 匯出至: + 匯出交易資料 + 匯出所有交易资料 + 預設情况下,自上次匯出後新增的交易才會被匯出。選擇此項後所有的交易都會被匯出。 + 匯出%1$s發生錯誤 + 匯出 + 匯出後刪除交易記錄 + 匯出完成後現存所有交易都會被刪除 + 設置 - SD卡 - DropBox - Google Drive + SD 卡 + Dropbox + Google 雲端硬碟 ownCloud - Send to… + 發送給... - 移动 - 移动 %1$d 交易 - 目的科目 - 访问 SD Card - 不能移动交易。\n两个科目的货币设置不一样。 - 常规 - 关于 - 选择默认货币 - 默认货币 - 创建科目时默认的货币 - 允许添加交易 - 允许创建科目 - GnuCash的数据 - 读取并修改GnuCash数据 - 记录交易 - 创建科目 - 显示科目 + 移動 + 移動 %1$d 交易 + 目標科目 + 訪問 SD 卡 + 不能移動交易。\n兩個會計科目的貨幣設置不一样。 + 一般設定 + 關於 + 選擇預設貨幣 + 預設貨幣 + 建立會計科目時預設的貨幣 + 允許添加交易 + 允許建立科目 + GnuCash的數據 + 讀取開修改GnuCash數據 + 記錄交易 + 建立會計科目 + 顯示科目名字 + Hide account balance in widget 创建科目 - 选择要创建的科目 - GnuCash里还没有科目信息。\n使用小部件前需要添加科目 + 選擇要建立的科目 + GnuCash裡還没有會計科目信息。\n使用小部件前需要添加會計科目 版本号 - 授权许可 - Apache License v2.0,点击查看明细(将打开网页)。 - 通用 - 选择科目 - 没有需要导出的交易 - 密码 - 密码设置 - 已开启密码保护 - 没有设置密码 - 修改密码 - 关于GnuCash - A mobile finance management and expense-tracker designed for Android - 关于 - %1$s文件保存到:\n - GnuCash Android %1$s 导出 - GnuCash Android Export from + 授權許可 + Apache License v2.0,點擊查看詳细(將打開網頁)。 + 一般偏好設定 + 選擇科目 + 没有需要匯出的交易 + 密碼 + 密碼設置 + 已開啟密碼保護 + 没有設置密碼 + 修改密碼 + 關於GnuCash + 专為 android 系統設計的財務管理和費用跟蹤軟體 + 關於 + 匯出到 %1$s 檔︰ \n + GnuCash Android %1$s 匯出 + GnuCash 匯出 交易 - 交易设置 - 科目设置 - 默认交易类型 - 默认的交易类型,借方或贷方 + 交易設置 + 科目設置 + 預設交易類型 + 預設的交易類型,借方或貸方 - 贷方 + 貸方 借方 - 确定删除所有交易? - 确定删除此项交易? - 导出设置 - 导出所有交易 - 删除已导出的交易 - email设置 - 默认发送导出的OFX文件到这个email地址,当然在导出过程时你仍然可以临时变更。 + 確定刪除所有交易? + 確定刪除此項交易? + 匯出設置 + 匯出所有交易 + 刪除已匯出的交易 + email設置 + 預設發送匯出的OFX文件到這個email地址,在匯出時你仍然可以改變email地址。 交易科目 - 所有交易会显示成两行,复式簿记 - 使用双行模式 - 帐户余额 - 需要输入科目名称 - 货币 + 所有交易會顯示成兩行,複式簿記 + 使用複式簿記 + 餘額 + 需要輸入科目名稱 + 貨幣 上级科目 - 添加 XML OFX头 - 当导出数据到GnuCash桌面版以外的程序时需要开启这个选项。 - 新功能 + 添加 XML OFX 檔頭 + 当匯出數據到GnuCash桌面版以外的程序時需要開啟這個選項。 + 更新內容 - - Support for multiple different books \n - - Adds ownCloud as destination for exports\n - - Compact view for transactions list\n - - Re-design of passcode lock screen\n - - Improved handling of scheduled transactions\n - - Multiple bug fixes and improvements\n - + - 支援多个帐簿 \n + - 支援 ownCloud \n + - 緊湊列表視圖\n + - 重新設計的密碼鎖屏\n + - 支援排程交易\n + - 多個 bug 修復\n 知道了 - 输入金额才能保存交易 - 不支持修改多币种的交易 - 导入GnuCash科目 - 导入科目 - 导入 GnuCash 科目中发生错误。 - GnuCash 科目资料导入完成。 - 导入从GnuCash桌面版导出的科目设置 - 导入GnuCash科目 - 删除科目资料的同时其下的交易信息也会被删除。 + 輸入金額才能保存交易 + 不支持修改多貨幣種類的交易 + 匯入GnuCash科目 + 匯入科目 + 匯入GnuCash科目时發生錯誤。 + GnuCash科目資料匯入完成。 + 匯入從GnuCash桌面版匯出的科目設置 + 匯入GnuCash科目 + 刪除科目資料的同時其下的交易信息也會被刪除。 - 删除所有科目 + 刪除所有科目 科目 所有科目都已删除 - 确定删除所有科目和交易? \n这个操作不能撤销! - - 帐户类型 - 所有科目的所有的交易信息将被删除! + 確定刪除所有科目和交易? \n這個操作不能撤銷! + 帳戶類型 + 所有科目的所有的交易信息將被刪除! 删除所有交易 所有交易都已删除 - 导入科目 - 点击再次确认,所有条目都将删除。 + 匯入科目 + 點擊再次確認,所有條目都將刪除。 交易 子科目 搜索 - 默认的导出格式 - 导出交易信息时使用的文件格式。 - 导出交易… - 重复 + 預設的匯出格式 + 匯出交易信息時使用的文件格式。 + 匯出交易… + 重複 - 不平衡的 - 正在导出交易信息 - 没有要显示的计划交易 - 计划交易已删除 - 占位符 - 默认的转账帐户 + 失調 + 正在匯出交易信息 + 没有要显示的排程交易 + 排程交易已刪除 + 標誌符 + 預設的轉賬帳戶 %d 子科目 - 现金 - 银行 + 現金 + 銀行 信用卡 - 资产 - 负债 + 資產 + 負債 收入 - 费用 - 应付账款 - 应收账款 - 所有者权益 - 货币 + 費用 + 應付賬款 + 應收賬款 + 所有者權益 + 貨幣 股票 共同基金 - 贸易 + 貿易 QIF @@ -203,108 +203,109 @@ 选择一种颜色 - 科目颜色和类型 + 科目顏色和類型 删除子科目 最近的 已加星标 所有 - 创建通用的科目结构 - 创建默认科目 - A new book will be opened with the default accounts\n\nYour current accounts and transactions will not be modified! - 计划的交易 - 欢迎使用GnuCash Android! \n你可以选择:1)创建常用的科目结构,2)导入自定义的科目结构。\或者稍后再决定,两种选择也能在设置中找到。 + 建立通用的科目結構 + 建立預設科目 + 将会创建新的账簿附带默认的科目 +现在这个账簿不会受到影响 + 計劃的交易 + 歡迎使用GnuCash Android! \n你可以選擇:1)建立常用的會計科目結構,2)匯入自定義的會計科目結構。\或者稍後再决定,兩種選擇也能在設置中找到。 - 计划的交易 - 选择存储的位置 + 交易 + 選擇儲存的位置 描述 - 花费 + 花費 收到 - 取款 + 提款 存款 - 支付 + 付款 费用 - 减少 + 減少 增加 收入 回扣 - 费用 - 支付 - 发票 - 买入 - 卖出 - 重复 - 还没有备份 - 期初余额 - 所有者权益 - 当删除所有交易后,还保持曾经的账户余额作为新的期初余额。 - 保存账户的期初余额 - OFX 格式不支持复式簿记 - 每种货币都会生成一个QIF文件 - 拆分交易 - 不平衡的: + 費用 + 賬單 + 發票 + 買入 + 賣出 + 重複 + 還没有備份 + 起始結餘 + 所有者權益 + 當刪除所有交易後,保留現存(刪除前)的帳戶餘額作為新的期初餘額。 + 保存账户的起始結餘 + OFX格式不支持複式簿記 + 每種貨幣都會產生一個QIF文件 + 分割交易 + 失調 添加一行 收藏 - Navigation drawer opened - Navigation drawer closed - 报表 - 饼图 - 折线图 - 柱状图 - 报表设置 - 报表使用的货币 - 用不同颜色区分科目 + 打开导航 + 关闭导航 + 報表 + 圓形圖 + 折線圖 + 橫條圖 + 報表設置 + 報表使用的貨幣 + 用不同顏色区分科目 在饼图中使用科目的颜色 - 报表 - 按数量排序 - Show legend - Show labels - Show percentage - Show average lines - 合并太小的数据 - 没有数据可显示 - 全部 - 总计 + 報表 + 按數量排序 + 顯示圖例 + 顯示標籤 + 顯示百分比 + 显示平均线 + 合併數目較小的數據 + 没有數據可顯示 + 总览 + 總計 其他 - The percentage of selected value calculated from the total amount - The percentage of selected value calculated from the current stacked bar amount + 所選值的百分比從總金額中計算 + 百分比按照柱状图比例计算 保存成模板 - 科目中包含交易信息。 \n如何处理交易信息 - 还存在子科目。 \n如何处理这些子科目 + 科目中包含交易信息。 \n如何處理交易信息 + 還存在子科目。 \n如何處理這些子科目 删除交易 - 请选择一个转账科目,否则在“设置”中关闭双航模式(复式簿记) - 点击然后创建计划交易 - 从备份恢复… - 备份和导出 - Enable DropBox - Enable ownCloud - 备份 - Enable exporting to DropBox - Enable exporting to ownCloud - Select GnuCash XML file - 备份设置 - 创建备份 - 备份会保存到SD卡上 - 选择恢复到哪一个备份 - 备份成功 - 备份失败 - 导出所有科目和交易 - Enable Google Drive - Enable exporting to Google Drive - 你需要安装一个文件管理器 - 选择备份 + 請選擇一個轉賬會計科目,或在“設置”中關閉複式簿記 + 點擊然後建立排程交易 + 從備份恢復… + 備份和匯出 + 啟用 DropBox + 啟用 ownCloud + 備份 + 啟用匯出到 DropBox + 啟用匯出到 ownCloud + 選擇GnuCash XML 檔 + 備份設置 + 建立備份 + 備份會保存到SD卡上 + 選擇恢復到哪一個備份 + 備份成功 + 備份失敗 + 匯出所有科目和交易 + 啟用 Google Drive + 啟用匯出到 Google Drive + 你需要安裝一個文件管理器 + 選擇備份 收藏 - 打开... - 报表 - 计划交易 - 导出... - 设置 - User Name - Password - owncloud + 打開... + 報表 + 排程交易 + 匯出... + 設置 + 帳號 + 密碼 + ownCloud https:// - OC server not found - OC username/password invalid - Invalid chars: \\ < > : \" | * ? + 伺服器找不到。 + 帳號/密碼無效 + 無效字元: \\ < > : \" | * ? OC server OK OC username/password OK Dir name OK @@ -320,101 +321,101 @@ 每 %d 年 - 启用崩溃日志 + 啟用故障日誌 Enable to send information about malfunctions to the developers for improvement (recommended). No user-identifiable information will be collected as part of this process! - Format - 找不到备份目录,请确认SD卡正常。 - 先输入现在的密码 - 请输入新密码 - 定时备份 - 定时备份 - 没有备份任务 - 创建定时备份 - 导出到:%1$s - The legend is too long - Account description - No recent accounts - No favorite accounts - Scheduled Actions + 格式 + 找不到備份目錄,請確認SD卡正常。 + 先輸入現在的密碼 + 請輸入新密碼 + 定時備份 + 定時備份 + 没有備份任務 + 建立定時備份 + 匯出到:%1$s + 圖例太長 + 描述 + 沒有最近的科目 + 沒有最星标的科目 + 計畫的操作 "Ended, last executed on " - Select a bar to view details - Next - Done - Default Currency - Account Setup - Select Currency - Feedback Options - Create default accounts - Import my accounts - Let me handle it - Other... - Automatically send crash reports - Disable crash reports - Back - Setup GnuCash - Welcome to GnuCash - Before you dive in, \nlet\'s setup a few things first\n\nTo continue, press Next - Split Editor - Check that all splits have valid amounts before saving! - Invalid expression! - Scheduled recurring transaction - An exchange rate is required - The converted amount is required - Transfer Funds - - Select a slice to see details - Period: - From: - To: - Provide either the converted amount or exchange rate in order to transfer funds - Exchange rate - Fetch quote - Converted Amount - Sheet - Expenses for last 3 months - Total Assets - Total Liabilities - Net Worth - Assets - Liabilities - Equity - - Move to: - Group By - Month - Quarter - Year - Balance Sheet - Total: - Google+ Community - Translate GnuCash - Share ideas, discuss changes or report problems - Translate or proof-read on CrowdIn - No compatible apps to receive the exported transactions! - Move… - Duplicate - Budgets - Cash Flow - Budgets - Enable compact view - Enable to always use compact view for transactions list - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s - Invalid amount + 選擇欄以查看詳細資訊 + 下一个 + 完成 + 預設貨幣: + 科目设置 + 選擇幣種 + 回饋選項 + 建立預設科目 + 汇入科目 + 稍后处理 + 其他... + 自動發送故障報告 + 禁用崩潰報告 + 後退 + 设置GnuCash + 歡迎來到GnuCash + 在使用之前,需 \n要设置几个参数\n\n请点击“下一步”繼續 + 拆分交易 + 保存之前请检查拆分交易的各项金额有效! + 運算式有誤 + 排程交易 + 需要填写匯率 + 没有填写换算好的金额 + 轉帳 + + 選擇一個切片以查看詳細資訊 + 时间段 + + + 提供轉換後的金額或匯率以轉移資金 + 匯率 + 獲取報價 + 轉換後的金額 + 工作表 + 過去 3 個月的費用 + 總資產: + 總負債 + 淨值 + 資產 + 負債 + 財產淨值 + + 移動至 + 分组方式 + + 季度 + + 資產負債表 + 總計 + Google+ 社群 + 翻譯GnuCash + 在Google+上提交问题和建议 + 帮忙翻譯或校對( CrowdIn) + 没有合适的应用接收汇出的文档 + 移動... + 複製 + 預算 + 現金流 + 預算 + 啟用紧凑視圖 + 交易清單總是啟用緊湊視圖 + 匯率不正確 + 例如 1 %1$s = x.xx %2$s + 無效金額 - Current month - Last 3 months - Last 6 months - Last 12 months - All time - Custom range… + 本月 + 過去三個月 + 過去六個月 + 過去 12 個月 + 全部 + 自訂範圍...... 1 - + 2 ABC 3 @@ -433,39 +434,40 @@ No user-identifiable information will be collected as part of this process! WXYZ 0 + - Manage Books - Manage Books… - Select any part of the chart to view details - Confirm delete Book - All accounts and transactions in this book will be deleted! - Delete Book - Last Exported: - Enable Sync - New Book - The selected transaction has no splits and cannot be opened - %1$d splits - in %1$s + 管理帐簿 + 管理帐簿 + 選擇該圖表以查看詳細資訊的任何部分 + 確認删除 + 帐簿中所有科目和交易都將被刪除 ! + 删除帐簿 + 最後匯出︰ + 啟用同步 + 新建帐簿 + 选择的交易没有拆分 + %1$d 项分割 + 于 %1$s - %d accounts + %d个科目 - %d transactions + %d个交易 - EXPENSE - INCOME + 費用 + 收入 - Connected to Google Drive - Unable to connect to Google Drive - Please enter an amount to split - external service - Updated transaction recurring schedule - Since - All time - Recommend in Play Store - until %1$s - on %1$s - for %1$s times - Compact View - Book %1$d + 連接到Google Drive + 無法連線到伺服器 + 請輸入要拆分的金額 + 外部服務 + 排程交易已经更新 + 自從 + 全部時間 + 在 Play Store 推薦 + 直到%1$s + 在%1$s + 共%1$s次 + 紧凑视图 + 账簿 %1$d + never diff --git a/app/src/main/res/values/donottranslate.xml b/app/src/main/res/values/donottranslate.xml index 5c88771bc..9f8fcf7b7 100644 --- a/app/src/main/res/values/donottranslate.xml +++ b/app/src/main/res/values/donottranslate.xml @@ -39,6 +39,7 @@ use_compact_list prefs_header_general + dropbox_access_token CREDIT DEBIT diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 058c5613e..77a0d09dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -21,6 +21,7 @@ Info Export… Add a new transaction to an account + View account details No accounts to display Account name Cancel @@ -63,7 +64,7 @@ Settings SD Card - DropBox + Dropbox Google Drive ownCloud Send to… @@ -85,6 +86,7 @@ Record transactions in GnuCash Create accounts in GnuCash Display account + Hide account balance in widget Create Accounts Select accounts to create No accounts exist in GnuCash.\nCreate an account before adding a widget diff --git a/app/src/main/res/xml/filepaths.xml b/app/src/main/res/xml/filepaths.xml new file mode 100644 index 000000000..c4435e624 --- /dev/null +++ b/app/src/main/res/xml/filepaths.xml @@ -0,0 +1,21 @@ + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/org/gnucash/android/test/unit/db/AccountsDbAdapterTest.java b/app/src/test/java/org/gnucash/android/test/unit/db/AccountsDbAdapterTest.java index 243c3bd09..20ec39710 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/db/AccountsDbAdapterTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/db/AccountsDbAdapterTest.java @@ -15,9 +15,7 @@ */ package org.gnucash.android.test.unit.db; -import android.content.Context; import android.database.sqlite.SQLiteDatabase; -import android.support.v7.preference.PreferenceManager; import org.assertj.core.data.Index; import org.gnucash.android.BuildConfig; @@ -60,7 +58,6 @@ import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; -import java.util.Currency; import java.util.List; import javax.xml.parsers.ParserConfigurationException; @@ -77,8 +74,9 @@ public class AccountsDbAdapterTest{ private AccountsDbAdapter mAccountsDbAdapter; private TransactionsDbAdapter mTransactionsDbAdapter; private SplitsDbAdapter mSplitsDbAdapter; + private CommoditiesDbAdapter mCommoditiesDbAdapter; - @Before + @Before public void setUp() throws Exception { initAdapters(null); } @@ -93,12 +91,14 @@ private void initAdapters(String bookUID){ mSplitsDbAdapter = SplitsDbAdapter.getInstance(); mTransactionsDbAdapter = TransactionsDbAdapter.getInstance(); mAccountsDbAdapter = AccountsDbAdapter.getInstance(); + mCommoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); } else { DatabaseHelper databaseHelper = new DatabaseHelper(GnuCashApplication.getAppContext(), bookUID); SQLiteDatabase db = databaseHelper.getWritableDatabase(); mSplitsDbAdapter = new SplitsDbAdapter(db); mTransactionsDbAdapter = new TransactionsDbAdapter(db, mSplitsDbAdapter); mAccountsDbAdapter = new AccountsDbAdapter(db, mTransactionsDbAdapter); + mCommoditiesDbAdapter = new CommoditiesDbAdapter(db); BooksDbAdapter.getInstance().setActive(bookUID); } } @@ -423,7 +423,7 @@ public void shouldReassignDescendantAccounts(){ public void shouldCreateImbalanceAccountOnDemand(){ assertThat(mAccountsDbAdapter.getRecordsCount()).isEqualTo(1L); - Currency usd = Currency.getInstance("USD"); + Commodity usd = mCommoditiesDbAdapter.getCommodity("USD"); String imbalanceUID = mAccountsDbAdapter.getImbalanceAccountUID(usd); assertThat(imbalanceUID).isNull(); assertThat(mAccountsDbAdapter.getRecordsCount()).isEqualTo(1L); diff --git a/app/src/test/java/org/gnucash/android/test/unit/db/ScheduledActionDbAdapterTest.java b/app/src/test/java/org/gnucash/android/test/unit/db/ScheduledActionDbAdapterTest.java index 0a513db6a..fd56a34f2 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/db/ScheduledActionDbAdapterTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/db/ScheduledActionDbAdapterTest.java @@ -65,8 +65,9 @@ public void everyScheduledActionShouldHaveRecurrence(){ public void testGenerateRepeatString(){ ScheduledAction scheduledAction = new ScheduledAction(ScheduledAction.ActionType.TRANSACTION); PeriodType periodType = PeriodType.MONTH; - periodType.setMultiplier(2); - scheduledAction.setRecurrence(new Recurrence(periodType)); + Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier(2); + scheduledAction.setRecurrence(recurrence); scheduledAction.setTotalPlannedExecutionCount(4); Resources res = GnuCashApplication.getAppContext().getResources(); String repeatString = res.getQuantityString(R.plurals.label_every_x_months, 2, 2) + ", " + diff --git a/app/src/test/java/org/gnucash/android/test/unit/db/TransactionsDbAdapterTest.java b/app/src/test/java/org/gnucash/android/test/unit/db/TransactionsDbAdapterTest.java index 245aa92b3..881fc5948 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/db/TransactionsDbAdapterTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/db/TransactionsDbAdapterTest.java @@ -142,7 +142,7 @@ public void testComputeBalance(){ savedBalance = transaction.getBalance(bravoAccount.getUID()); assertThat(savedBalance.getNumerator()).isEqualTo(secondSplitAmount.negate().getNumerator()); - assertThat(savedBalance.getCurrency()).isEqualTo(secondSplitAmount.getCurrency()); + assertThat(savedBalance.getCommodity()).isEqualTo(secondSplitAmount.getCommodity()); } @After diff --git a/app/src/test/java/org/gnucash/android/test/unit/export/OfxExporterTest.java b/app/src/test/java/org/gnucash/android/test/unit/export/OfxExporterTest.java new file mode 100644 index 000000000..58cd6e9b4 --- /dev/null +++ b/app/src/test/java/org/gnucash/android/test/unit/export/OfxExporterTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2016 Àlex Magaz Graça + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gnucash.android.test.unit.export; + +import android.database.sqlite.SQLiteDatabase; + +import org.gnucash.android.BuildConfig; +import org.gnucash.android.app.GnuCashApplication; +import org.gnucash.android.db.BookDbHelper; +import org.gnucash.android.db.DatabaseHelper; +import org.gnucash.android.db.adapter.BooksDbAdapter; +import org.gnucash.android.export.ExportFormat; +import org.gnucash.android.export.ExportParams; +import org.gnucash.android.export.ofx.OfxExporter; +import org.gnucash.android.model.Book; +import org.gnucash.android.test.unit.testutil.GnucashTestRunner; +import org.gnucash.android.test.unit.testutil.ShadowCrashlytics; +import org.gnucash.android.test.unit.testutil.ShadowUserVoice; +import org.gnucash.android.util.TimestampHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import static org.assertj.core.api.Assertions.assertThat; + + +@RunWith(GnucashTestRunner.class) //package is required so that resources can be found in dev mode +@Config(constants = BuildConfig.class, + sdk = 21, + packageName = "org.gnucash.android", + shadows = {ShadowCrashlytics.class, ShadowUserVoice.class}) +public class OfxExporterTest { + private SQLiteDatabase mDb; + + @Before + public void setUp() throws Exception { + BookDbHelper bookDbHelper = new BookDbHelper(GnuCashApplication.getAppContext()); + BooksDbAdapter booksDbAdapter = new BooksDbAdapter(bookDbHelper.getWritableDatabase()); + Book testBook = new Book("testRootAccountUID"); + booksDbAdapter.addRecord(testBook); + DatabaseHelper databaseHelper = + new DatabaseHelper(GnuCashApplication.getAppContext(), testBook.getUID()); + mDb = databaseHelper.getWritableDatabase(); + } + + /** + * When there aren't new or modified transactions, the OFX exporter + * shouldn't create any file. + */ + @Test + public void testWithNoTransactionsToExport_shouldNotCreateAnyFile(){ + ExportParams exportParameters = new ExportParams(ExportFormat.OFX); + exportParameters.setExportStartTime(TimestampHelper.getTimestampFromEpochZero()); + exportParameters.setExportTarget(ExportParams.ExportTarget.SD_CARD); + exportParameters.setDeleteTransactionsAfterExport(false); + OfxExporter exporter = new OfxExporter(exportParameters, mDb); + assertThat(exporter.generateExport()).isEmpty(); + } +} \ No newline at end of file diff --git a/app/src/test/java/org/gnucash/android/test/unit/export/QifExporterTest.java b/app/src/test/java/org/gnucash/android/test/unit/export/QifExporterTest.java new file mode 100644 index 000000000..5f17fe4a2 --- /dev/null +++ b/app/src/test/java/org/gnucash/android/test/unit/export/QifExporterTest.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016 Àlex Magaz Graça + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gnucash.android.test.unit.export; + +import android.database.sqlite.SQLiteDatabase; + +import org.gnucash.android.BuildConfig; +import org.gnucash.android.app.GnuCashApplication; +import org.gnucash.android.db.BookDbHelper; +import org.gnucash.android.db.DatabaseHelper; +import org.gnucash.android.db.adapter.BooksDbAdapter; +import org.gnucash.android.export.ExportFormat; +import org.gnucash.android.export.ExportParams; +import org.gnucash.android.export.qif.QifExporter; +import org.gnucash.android.model.Book; +import org.gnucash.android.test.unit.testutil.GnucashTestRunner; +import org.gnucash.android.test.unit.testutil.ShadowCrashlytics; +import org.gnucash.android.test.unit.testutil.ShadowUserVoice; +import org.gnucash.android.util.TimestampHelper; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; + +import static org.assertj.core.api.Assertions.assertThat; + +@RunWith(GnucashTestRunner.class) //package is required so that resources can be found in dev mode +@Config(constants = BuildConfig.class, + sdk = 21, + packageName = "org.gnucash.android", + shadows = {ShadowCrashlytics.class, ShadowUserVoice.class}) +public class QifExporterTest { + private SQLiteDatabase mDb; + + @Before + public void setUp() throws Exception { + BookDbHelper bookDbHelper = new BookDbHelper(GnuCashApplication.getAppContext()); + BooksDbAdapter booksDbAdapter = new BooksDbAdapter(bookDbHelper.getWritableDatabase()); + Book testBook = new Book("testRootAccountUID"); + booksDbAdapter.addRecord(testBook); + DatabaseHelper databaseHelper = + new DatabaseHelper(GnuCashApplication.getAppContext(), testBook.getUID()); + mDb = databaseHelper.getWritableDatabase(); + } + + /** + * When there aren't new or modified transactions, the QIF exporter + * shouldn't create any file. + */ + @Test + public void testWithNoTransactionsToExport_shouldNotCreateAnyFile(){ + ExportParams exportParameters = new ExportParams(ExportFormat.QIF); + exportParameters.setExportStartTime(TimestampHelper.getTimestampFromEpochZero()); + exportParameters.setExportTarget(ExportParams.ExportTarget.SD_CARD); + exportParameters.setDeleteTransactionsAfterExport(false); + QifExporter exporter = new QifExporter(exportParameters, mDb); + assertThat(exporter.generateExport()).isEmpty(); + } +} \ No newline at end of file diff --git a/app/src/test/java/org/gnucash/android/test/unit/importer/GncXmlHandlerTest.java b/app/src/test/java/org/gnucash/android/test/unit/importer/GncXmlHandlerTest.java new file mode 100644 index 000000000..7b617eb46 --- /dev/null +++ b/app/src/test/java/org/gnucash/android/test/unit/importer/GncXmlHandlerTest.java @@ -0,0 +1,377 @@ +/* + * Copyright (c) 2016 Àlex Magaz Graça + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.gnucash.android.test.unit.importer; + +import android.database.sqlite.SQLiteDatabase; + +import org.gnucash.android.BuildConfig; +import org.gnucash.android.app.GnuCashApplication; +import org.gnucash.android.db.DatabaseHelper; +import org.gnucash.android.db.adapter.AccountsDbAdapter; +import org.gnucash.android.db.adapter.BooksDbAdapter; +import org.gnucash.android.db.adapter.SplitsDbAdapter; +import org.gnucash.android.db.adapter.TransactionsDbAdapter; +import org.gnucash.android.export.xml.GncXmlHelper; +import org.gnucash.android.importer.GncXmlHandler; +import org.gnucash.android.model.Account; +import org.gnucash.android.model.AccountType; +import org.gnucash.android.model.Money; +import org.gnucash.android.model.Split; +import org.gnucash.android.model.Transaction; +import org.gnucash.android.model.TransactionType; +import org.gnucash.android.test.unit.testutil.GnucashTestRunner; +import org.gnucash.android.test.unit.testutil.ShadowCrashlytics; +import org.gnucash.android.test.unit.testutil.ShadowUserVoice; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.annotation.Config; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.ParseException; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; + +/** + * Imports GnuCash XML files and checks the objects defined in them are imported correctly. + */ +@RunWith(GnucashTestRunner.class) +@Config(constants = BuildConfig.class, sdk = 21, packageName = "org.gnucash.android", shadows = {ShadowCrashlytics.class, ShadowUserVoice.class}) +public class GncXmlHandlerTest { + private BooksDbAdapter mBooksDbAdapter; + private TransactionsDbAdapter mTransactionsDbAdapter; + private AccountsDbAdapter mAccountsDbAdapter; + + @Before + public void setUp() throws Exception { + mBooksDbAdapter = BooksDbAdapter.getInstance(); + mBooksDbAdapter.deleteAllRecords(); + assertThat(mBooksDbAdapter.getRecordsCount()).isZero(); + } + + private String importGnuCashXml(String filename) { + SAXParser parser; + GncXmlHandler handler = null; + try { + parser = SAXParserFactory.newInstance().newSAXParser(); + XMLReader reader = parser.getXMLReader(); + handler = new GncXmlHandler(); + reader.setContentHandler(handler); + InputStream inputStream = getClass().getClassLoader().getResourceAsStream(filename); + InputSource inputSource = new InputSource(new BufferedInputStream(inputStream)); + reader.parse(inputSource); + } catch (ParserConfigurationException | SAXException | IOException e) { + e.printStackTrace(); + fail(); + } + return handler.getBookUID(); + } + + private void setUpDbAdapters(String bookUID) { + DatabaseHelper databaseHelper = new DatabaseHelper(GnuCashApplication.getAppContext(), bookUID); + SQLiteDatabase mainDb = databaseHelper.getReadableDatabase(); + mTransactionsDbAdapter = new TransactionsDbAdapter(mainDb, new SplitsDbAdapter(mainDb)); + mAccountsDbAdapter = new AccountsDbAdapter(mainDb, mTransactionsDbAdapter); + } + + /** + * Tests basic accounts import. + * + *

Checks hierarchy and attributes. We should have:

+ *
+     * Root
+     * |_ Assets
+     * |   |_ Cash in wallet
+     * |_ Expenses
+     *     |_ Dining
+     * 
+ */ + @Test + public void accountsImport() { + String bookUID = importGnuCashXml("accountsImport.xml"); + setUpDbAdapters(bookUID); + + assertThat(mAccountsDbAdapter.getRecordsCount()).isEqualTo(5); // 4 accounts + root + + Account rootAccount = mAccountsDbAdapter.getRecord("308ade8cf0be2b0b05c5eec3114a65fa"); + assertThat(rootAccount.getParentUID()).isNull(); + assertThat(rootAccount.getName()).isEqualTo("Root Account"); + assertThat(rootAccount.isHidden()).isTrue(); + + Account assetsAccount = mAccountsDbAdapter.getRecord("3f44d61cb1afd201e8ea5a54ec4fbbff"); + assertThat(assetsAccount.getParentUID()).isEqualTo(rootAccount.getUID()); + assertThat(assetsAccount.getName()).isEqualTo("Assets"); + assertThat(assetsAccount.isHidden()).isFalse(); + assertThat(assetsAccount.isPlaceholderAccount()).isTrue(); + assertThat(assetsAccount.getAccountType()).isEqualTo(AccountType.ASSET); + + Account diningAccount = mAccountsDbAdapter.getRecord("6a7cf8267314992bdddcee56d71a3908"); + assertThat(diningAccount.getParentUID()).isEqualTo("9b607f63aecb1a175556676904432365"); + assertThat(diningAccount.getName()).isEqualTo("Dining"); + assertThat(diningAccount.getDescription()).isEqualTo("Dining"); + assertThat(diningAccount.isHidden()).isFalse(); + assertThat(diningAccount.isPlaceholderAccount()).isFalse(); + assertThat(diningAccount.isFavorite()).isFalse(); + assertThat(diningAccount.getAccountType()).isEqualTo(AccountType.EXPENSE); + assertThat(diningAccount.getCommodity().getCurrencyCode()).isEqualTo("USD"); + assertThat(diningAccount.getColor()).isEqualTo(Account.DEFAULT_COLOR); + assertThat(diningAccount.getDefaultTransferAccountUID()).isNull(); + } + + /** + * Tests importing a simple transaction with default splits. + * + * @throws ParseException + */ + @Test + public void simpleTransactionImport() throws ParseException { + String bookUID = importGnuCashXml("simpleTransactionImport.xml"); + setUpDbAdapters(bookUID); + + assertThat(mTransactionsDbAdapter.getRecordsCount()).isEqualTo(1); + + Transaction transaction = mTransactionsDbAdapter.getRecord("b33c8a6160494417558fd143731fc26a"); + + // Check attributes + assertThat(transaction.getDescription()).isEqualTo("Kahuna Burger"); + assertThat(transaction.getCommodity().getCurrencyCode()).isEqualTo("USD"); + assertThat(transaction.getNote()).isEqualTo(""); + assertThat(transaction.getScheduledActionUID()).isNull(); + assertThat(transaction.isExported()).isTrue(); + assertThat(transaction.isTemplate()).isFalse(); + assertThat(transaction.getTimeMillis()). + isEqualTo(GncXmlHelper.parseDate("2016-08-23 00:00:00 +0200")); + assertThat(transaction.getCreatedTimestamp().getTime()). + isEqualTo(GncXmlHelper.parseDate("2016-08-23 12:44:19 +0200")); + + // Check splits + assertThat(transaction.getSplits().size()).isEqualTo(2); + // FIXME: don't depend on the order + Split split1 = transaction.getSplits().get(0); + assertThat(split1.getUID()).isEqualTo("ad2cbc774fc4e71885d17e6932448e8e"); + assertThat(split1.getAccountUID()).isEqualTo("6a7cf8267314992bdddcee56d71a3908"); + assertThat(split1.getTransactionUID()).isEqualTo("b33c8a6160494417558fd143731fc26a"); + assertThat(split1.getType()).isEqualTo(TransactionType.DEBIT); + assertThat(split1.getMemo()).isNull(); + assertThat(split1.getValue()).isEqualTo(new Money("10", "USD")); + assertThat(split1.getQuantity()).isEqualTo(new Money("10", "USD")); + assertThat(split1.getReconcileState()).isEqualTo('n'); + + Split split2 = transaction.getSplits().get(1); + assertThat(split2.getUID()).isEqualTo("61d4d604bc00a59cabff4e8875d00bee"); + assertThat(split2.getAccountUID()).isEqualTo("dae686a1636addc0dae1ae670701aa4a"); + assertThat(split2.getTransactionUID()).isEqualTo("b33c8a6160494417558fd143731fc26a"); + assertThat(split2.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(split2.getMemo()).isNull(); + assertThat(split2.getValue()).isEqualTo(new Money("10", "USD")); + assertThat(split2.getQuantity()).isEqualTo(new Money("10", "USD")); + assertThat(split2.getReconcileState()).isEqualTo('n'); + assertThat(split2.isPairOf(split1)).isTrue(); + } + + /** + * Tests importing a transaction with non-default splits. + * + * @throws ParseException + */ + @Test + public void transactionWithNonDefaultSplitsImport() throws ParseException { + String bookUID = importGnuCashXml("transactionWithNonDefaultSplitsImport.xml"); + setUpDbAdapters(bookUID); + + assertThat(mTransactionsDbAdapter.getRecordsCount()).isEqualTo(1); + + Transaction transaction = mTransactionsDbAdapter.getRecord("042ff745a80e94e6237fb0549f6d32ae"); + + // Ensure it's the correct one + assertThat(transaction.getDescription()).isEqualTo("Tandoori Mahal"); + + // Check splits + assertThat(transaction.getSplits().size()).isEqualTo(3); + // FIXME: don't depend on the order + Split expenseSplit = transaction.getSplits().get(0); + assertThat(expenseSplit.getUID()).isEqualTo("c50cce06e2bf9085730821c82d0b36ca"); + assertThat(expenseSplit.getAccountUID()).isEqualTo("6a7cf8267314992bdddcee56d71a3908"); + assertThat(expenseSplit.getTransactionUID()).isEqualTo("042ff745a80e94e6237fb0549f6d32ae"); + assertThat(expenseSplit.getType()).isEqualTo(TransactionType.DEBIT); + assertThat(expenseSplit.getMemo()).isNull(); + assertThat(expenseSplit.getValue()).isEqualTo(new Money("50", "USD")); + assertThat(expenseSplit.getQuantity()).isEqualTo(new Money("50", "USD")); + + Split assetSplit1 = transaction.getSplits().get(1); + assertThat(assetSplit1.getUID()).isEqualTo("4930f412665a705eedba39789b6c3a35"); + assertThat(assetSplit1.getAccountUID()).isEqualTo("dae686a1636addc0dae1ae670701aa4a"); + assertThat(assetSplit1.getTransactionUID()).isEqualTo("042ff745a80e94e6237fb0549f6d32ae"); + assertThat(assetSplit1.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(assetSplit1.getMemo()).isEqualTo("tip"); + assertThat(assetSplit1.getValue()).isEqualTo(new Money("5", "USD")); + assertThat(assetSplit1.getQuantity()).isEqualTo(new Money("5", "USD")); + assertThat(assetSplit1.isPairOf(expenseSplit)).isFalse(); + + Split assetSplit2 = transaction.getSplits().get(2); + assertThat(assetSplit2.getUID()).isEqualTo("b97cd9bbaa17f181d0a5b39b260dabda"); + assertThat(assetSplit2.getAccountUID()).isEqualTo("ee139a5658a0d37507dc26284798e347"); + assertThat(assetSplit2.getTransactionUID()).isEqualTo("042ff745a80e94e6237fb0549f6d32ae"); + assertThat(assetSplit2.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(assetSplit2.getMemo()).isNull(); + assertThat(assetSplit2.getValue()).isEqualTo(new Money("45", "USD")); + assertThat(assetSplit2.getQuantity()).isEqualTo(new Money("45", "USD")); + assertThat(assetSplit2.isPairOf(expenseSplit)).isFalse(); + } + + /** + * Tests importing a transaction with multiple currencies. + * + * @throws ParseException + */ + @Test + public void multiCurrencyTransactionImport() throws ParseException { + String bookUID = importGnuCashXml("multiCurrencyTransactionImport.xml"); + setUpDbAdapters(bookUID); + + assertThat(mTransactionsDbAdapter.getRecordsCount()).isEqualTo(1); + + Transaction transaction = mTransactionsDbAdapter.getRecord("ded49386f8ea319ccaee043ba062b3e1"); + + // Ensure it's the correct one + assertThat(transaction.getDescription()).isEqualTo("Salad express"); + assertThat(transaction.getCommodity().getCurrencyCode()).isEqualTo("USD"); + + // Check splits + assertThat(transaction.getSplits().size()).isEqualTo(2); + // FIXME: don't depend on the order + Split split1 = transaction.getSplits().get(0); + assertThat(split1.getUID()).isEqualTo("88bbbbac7689a8657b04427f8117a783"); + assertThat(split1.getAccountUID()).isEqualTo("6a7cf8267314992bdddcee56d71a3908"); + assertThat(split1.getTransactionUID()).isEqualTo("ded49386f8ea319ccaee043ba062b3e1"); + assertThat(split1.getType()).isEqualTo(TransactionType.DEBIT); + assertThat(split1.getValue()).isEqualTo(new Money("20", "USD")); + assertThat(split1.getQuantity()).isEqualTo(new Money("20", "USD")); + + Split split2 = transaction.getSplits().get(1); + assertThat(split2.getUID()).isEqualTo("e0dd885065bfe3c9ef63552fe84c6d23"); + assertThat(split2.getAccountUID()).isEqualTo("0469e915a22ba7846aca0e69f9f9b683"); + assertThat(split2.getTransactionUID()).isEqualTo("ded49386f8ea319ccaee043ba062b3e1"); + assertThat(split2.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(split2.getValue()).isEqualTo(new Money("20", "USD")); + assertThat(split2.getQuantity()).isEqualTo(new Money("17.93", "EUR")); + assertThat(split2.isPairOf(split1)).isTrue(); + } + + /** + * Tests importing a simple scheduled transaction with default splits. + */ + //@Test Disabled as currently amounts are only read from credit/debit-numeric + // slots and transactions without amount are ignored. + public void simpleScheduledTransactionImport() throws ParseException { + String bookUID = importGnuCashXml("simpleScheduledTransactionImport.xml"); + setUpDbAdapters(bookUID); + + assertThat(mTransactionsDbAdapter.getTemplateTransactionsCount()).isEqualTo(1); + + Transaction scheduledTransaction = + mTransactionsDbAdapter.getRecord("b645bef06d0844aece6424ceeec03983"); + + // Check attributes + assertThat(scheduledTransaction.getDescription()).isEqualTo("Los pollos hermanos"); + assertThat(scheduledTransaction.getCommodity().getCurrencyCode()).isEqualTo("USD"); + assertThat(scheduledTransaction.getNote()).isEqualTo(""); + assertThat(scheduledTransaction.getScheduledActionUID()).isNull(); + assertThat(scheduledTransaction.isExported()).isTrue(); + assertThat(scheduledTransaction.isTemplate()).isTrue(); + assertThat(scheduledTransaction.getTimeMillis()) + .isEqualTo(GncXmlHelper.parseDate("2016-08-24 00:00:00 +0200")); + assertThat(scheduledTransaction.getCreatedTimestamp().getTime()) + .isEqualTo(GncXmlHelper.parseDate("2016-08-24 19:50:15 +0200")); + + // Check splits + assertThat(scheduledTransaction.getSplits().size()).isEqualTo(2); + + Split split1 = scheduledTransaction.getSplits().get(0); + assertThat(split1.getUID()).isEqualTo("f66794ef262aac3ae085ecc3030f2769"); + assertThat(split1.getAccountUID()).isEqualTo("6a7cf8267314992bdddcee56d71a3908"); + assertThat(split1.getTransactionUID()).isEqualTo("b645bef06d0844aece6424ceeec03983"); + assertThat(split1.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(split1.getMemo()).isNull(); + assertThat(split1.getValue()).isEqualTo(new Money("20", "USD")); + // FIXME: the quantity is always 0 as it's set from instead + // of from the slots + //assertThat(split1.getQuantity()).isEqualTo(new Money("20", "USD")); + + Split split2 = scheduledTransaction.getSplits().get(1); + assertThat(split2.getUID()).isEqualTo("57e2be6ca6b568f8f7c9b2e455e1e21f"); + assertThat(split2.getAccountUID()).isEqualTo("dae686a1636addc0dae1ae670701aa4a"); + assertThat(split2.getTransactionUID()).isEqualTo("b645bef06d0844aece6424ceeec03983"); + assertThat(split2.getType()).isEqualTo(TransactionType.DEBIT); + assertThat(split2.getMemo()).isNull(); + assertThat(split2.getValue()).isEqualTo(new Money("20", "USD")); + // FIXME: the quantity is always 0 as it's set from instead + // of from the slots + //assertThat(split2.getQuantity()).isEqualTo(new Money("20", "USD")); + assertThat(split2.isPairOf(split1)).isTrue(); + } + + /** + * Checks for bug 562 - Scheduled transaction imported with imbalanced splits. + * + *

Happens when an scheduled transaction is defined with both credit and + * debit slots in each split.

+ */ + @Test + public void bug562_scheduledTransactionImportedWithImbalancedSplits() throws ParseException { + String bookUID = importGnuCashXml("bug562_scheduledTransactionImportedWithImbalancedSplits.xml"); + setUpDbAdapters(bookUID); + + assertThat(mTransactionsDbAdapter.getTemplateTransactionsCount()).isEqualTo(1); + + Transaction scheduledTransaction = + mTransactionsDbAdapter.getRecord("b645bef06d0844aece6424ceeec03983"); + + // Ensure it's the correct transaction + assertThat(scheduledTransaction.getDescription()).isEqualTo("Los pollos hermanos"); + assertThat(scheduledTransaction.isTemplate()).isTrue(); + + // Check splits + assertThat(scheduledTransaction.getSplits().size()).isEqualTo(2); + + Split split1 = scheduledTransaction.getSplits().get(0); + assertThat(split1.getAccountUID()).isEqualTo("6a7cf8267314992bdddcee56d71a3908"); + assertThat(split1.getType()).isEqualTo(TransactionType.CREDIT); + assertThat(split1.getValue()).isEqualTo(new Money("20", "USD")); + // FIXME: the quantity is always 0 as it's set from instead + // of from the slots + //assertThat(split1.getQuantity()).isEqualTo(new Money("20", "USD")); + + Split split2 = scheduledTransaction.getSplits().get(1); + assertThat(split2.getAccountUID()).isEqualTo("dae686a1636addc0dae1ae670701aa4a"); + assertThat(split2.getType()).isEqualTo(TransactionType.DEBIT); + assertThat(split2.getValue()).isEqualTo(new Money("20", "USD")); + // FIXME: the quantity is always 0 as it's set from instead + // of from the slots + //assertThat(split2.getQuantity()).isEqualTo(new Money("20", "USD")); + assertThat(split2.isPairOf(split1)).isTrue(); + } +} \ No newline at end of file diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/MoneyTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/MoneyTest.java index 4ad9496de..d1ba60ced 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/MoneyTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/MoneyTest.java @@ -172,7 +172,7 @@ public void testPrinting(){ public void validateImmutability(){ assertEquals(mHashcode, mMoneyInEur.hashCode()); assertEquals(amountString, mMoneyInEur.toPlainString()); - assertEquals(CURRENCY_CODE, mMoneyInEur.getCurrency().getCurrencyCode()); + assertEquals(CURRENCY_CODE, mMoneyInEur.getCommodity().getCurrencyCode()); } } diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/RecurrenceTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/RecurrenceTest.java index d5cd10afe..5f76ff6e7 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/RecurrenceTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/RecurrenceTest.java @@ -56,6 +56,18 @@ public void testRecurrenceCountComputation(){ recurrence.setPeriodEnd(new Timestamp(end.getMillis())); assertThat(recurrence.getCount()).isEqualTo(10); + + //test case where last appointment is just a little before end time, but not a complete period since last + DateTime startTime = new DateTime(2016, 6, 6, 9, 0); + DateTime endTime = new DateTime(2016, 8, 29, 10, 0); + PeriodType biWeekly = PeriodType.WEEK; + recurrence = new Recurrence(biWeekly); + recurrence.setMultiplier(2); + recurrence.setPeriodStart(new Timestamp(startTime.getMillis())); + recurrence.setPeriodEnd(new Timestamp(endTime.getMillis())); + + assertThat(recurrence.getCount()).isEqualTo(7); + } /** diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/ScheduledActionTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/ScheduledActionTest.java index 89b0fe430..8ce1b4c7d 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/ScheduledActionTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/ScheduledActionTest.java @@ -98,9 +98,9 @@ public void settingRecurrence_shouldSetEndTime(){ public void testComputingNextScheduledExecution(){ ScheduledAction scheduledAction = new ScheduledAction(ScheduledAction.ActionType.TRANSACTION); PeriodType periodType = PeriodType.MONTH; - periodType.setMultiplier(2); Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier(2); DateTime startDate = new DateTime(2015, 8, 15, 12, 0); recurrence.setPeriodStart(new Timestamp(startDate.getMillis())); scheduledAction.setRecurrence(recurrence); @@ -116,8 +116,8 @@ public void testComputingNextScheduledExecution(){ public void testComputingTimeOfLastSchedule(){ ScheduledAction scheduledAction = new ScheduledAction(ScheduledAction.ActionType.TRANSACTION); PeriodType periodType = PeriodType.WEEK; - periodType.setMultiplier(2); Recurrence recurrence = new Recurrence(periodType); + recurrence.setMultiplier(2); scheduledAction.setRecurrence(recurrence); DateTime startDate = new DateTime(2016, 6, 6, 9, 0); scheduledAction.setStartTime(startDate.getMillis()); diff --git a/app/src/test/java/org/gnucash/android/test/unit/service/ScheduledActionServiceTest.java b/app/src/test/java/org/gnucash/android/test/unit/service/ScheduledActionServiceTest.java index ac1db752e..094c5234c 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/service/ScheduledActionServiceTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/service/ScheduledActionServiceTest.java @@ -198,7 +198,8 @@ public void missedScheduledTransactions_shouldBeGenerated(){ scheduledAction.setActionUID(mActionUID); - scheduledAction.setRecurrence(PeriodType.WEEK, 2); + int multiplier = 2; + scheduledAction.setRecurrence(PeriodType.WEEK, multiplier); ScheduledActionDbAdapter.getInstance().addRecord(scheduledAction, DatabaseAdapter.UpdateMethod.insert); TransactionsDbAdapter transactionsDbAdapter = TransactionsDbAdapter.getInstance(); diff --git a/app/src/test/resources/accountsImport.xml b/app/src/test/resources/accountsImport.xml new file mode 100644 index 000000000..91be43d1a --- /dev/null +++ b/app/src/test/resources/accountsImport.xml @@ -0,0 +1,147 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +5 + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + + + + + diff --git a/app/src/test/resources/bug562_scheduledTransactionImportedWithImbalancedSplits.xml b/app/src/test/resources/bug562_scheduledTransactionImportedWithImbalancedSplits.xml new file mode 100644 index 000000000..040f0f881 --- /dev/null +++ b/app/src/test/resources/bug562_scheduledTransactionImportedWithImbalancedSplits.xml @@ -0,0 +1,348 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +7 +1 +1 + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Bank + ba516a06fb7c7a0506365c7e28e17532 + BANK + + ISO4217 + USD + + 100 + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + Imbalance-USD + e6b31cde6324bbf0bec4182628b6d132 + BANK + + ISO4217 + USD + + 100 + 308ade8cf0be2b0b05c5eec3114a65fa + + + 04e2b1077b5f92b017dcc96e7730f4f7 + + ISO4217 + USD + + + 2016-08-24 00:00:00 +0200 + + + 2016-08-24 19:49:32 +0200 + + Los pollos hermanos + + + date-posted + + 2016-08-24 + + + + + + 4ee126eb8128a194bdce64ac793ad917 + n + 2000/100 + 2000/100 + 6a7cf8267314992bdddcee56d71a3908 + + + 8834488bbc36d9431f8c1fa6a23c4b43 + n + -2000/100 + -2000/100 + dae686a1636addc0dae1ae670701aa4a + + + + + + Template Root + d3d90433396f0ca44c337adb0f565c74 + ROOT + + + 9def659b35e85b09fe2bfade35053487 + 2e9b02b5ed6fb07c7d4536bb8a03599e + BANK + + template + template + + 1 + d3d90433396f0ca44c337adb0f565c74 + + + b645bef06d0844aece6424ceeec03983 + + ISO4217 + USD + + + 2016-08-24 00:00:00 +0200 + + + 2016-08-24 19:50:15 +0200 + + Los pollos hermanos + + + date-posted + + 2016-08-24 + + + + + + f66794ef262aac3ae085ecc3030f2769 + n + 0/100 + 0/1 + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + sched-xaction + + + account + 6a7cf8267314992bdddcee56d71a3908 + + + credit-formula + 20 + + + credit-numeric + 20/1 + + + debit-formula + + + + debit-numeric + 0/1 + + + + + + + 57e2be6ca6b568f8f7c9b2e455e1e21f + n + 0/100 + 0/1 + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + sched-xaction + + + account + dae686a1636addc0dae1ae670701aa4a + + + credit-formula + + + + credit-numeric + 0/1 + + + debit-formula + 20 + + + debit-numeric + 20/1 + + + + + + + + + + 9def659b35e85b09fe2bfade35053487 + Los pollos hermanos + y + n + n + 0 + 0 + 1 + + 2016-09-24 + + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + 1 + month + + 2016-07-24 + + + + + + + + + + diff --git a/app/src/test/resources/multiCurrencyTransactionImport.xml b/app/src/test/resources/multiCurrencyTransactionImport.xml new file mode 100644 index 000000000..9cb22d9f8 --- /dev/null +++ b/app/src/test/resources/multiCurrencyTransactionImport.xml @@ -0,0 +1,230 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +6 +1 +1 + + ISO4217 + EUR + + currency + + + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + + 8622e90f9ba655d4170d24fcfd55504f + + ISO4217 + EUR + + + ISO4217 + USD + + + 2016-09-18 20:23:55 +0200 + + Finance::Quote + last + 111530000/100000000 + + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Euro Bank + 0469e915a22ba7846aca0e69f9f9b683 + BANK + + ISO4217 + EUR + + 100 + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + ded49386f8ea319ccaee043ba062b3e1 + + ISO4217 + USD + + + 2016-09-18 00:00:00 +0200 + + + 2016-09-18 20:24:06 +0200 + + Salad express + + + date-posted + + 2016-09-18 + + + + + + 88bbbbac7689a8657b04427f8117a783 + n + 2000/100 + 2000/100 + 6a7cf8267314992bdddcee56d71a3908 + + + e0dd885065bfe3c9ef63552fe84c6d23 + n + -2000/100 + -1793/100 + 0469e915a22ba7846aca0e69f9f9b683 + + + + + + + + + diff --git a/app/src/test/resources/simpleScheduledTransactionImport.xml b/app/src/test/resources/simpleScheduledTransactionImport.xml new file mode 100644 index 000000000..bd6c489fb --- /dev/null +++ b/app/src/test/resources/simpleScheduledTransactionImport.xml @@ -0,0 +1,324 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +7 +1 +1 + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Bank + ba516a06fb7c7a0506365c7e28e17532 + BANK + + ISO4217 + USD + + 100 + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + Imbalance-USD + e6b31cde6324bbf0bec4182628b6d132 + BANK + + ISO4217 + USD + + 100 + 308ade8cf0be2b0b05c5eec3114a65fa + + + 04e2b1077b5f92b017dcc96e7730f4f7 + + ISO4217 + USD + + + 2016-08-24 00:00:00 +0200 + + + 2016-08-24 19:49:32 +0200 + + Los pollos hermanos + + + date-posted + + 2016-08-24 + + + + + + 4ee126eb8128a194bdce64ac793ad917 + n + 2000/100 + 2000/100 + 6a7cf8267314992bdddcee56d71a3908 + + + 8834488bbc36d9431f8c1fa6a23c4b43 + n + -2000/100 + -2000/100 + dae686a1636addc0dae1ae670701aa4a + + + + + + Template Root + d3d90433396f0ca44c337adb0f565c74 + ROOT + + + 9def659b35e85b09fe2bfade35053487 + 2e9b02b5ed6fb07c7d4536bb8a03599e + BANK + + template + template + + 1 + d3d90433396f0ca44c337adb0f565c74 + + + b645bef06d0844aece6424ceeec03983 + + ISO4217 + USD + + + 2016-08-24 00:00:00 +0200 + + + 2016-08-24 19:50:15 +0200 + + Los pollos hermanos + + + date-posted + + 2016-08-24 + + + + + + f66794ef262aac3ae085ecc3030f2769 + n + 0/100 + 0/1 + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + sched-xaction + + + account + 6a7cf8267314992bdddcee56d71a3908 + + + debit-formula + 20.00 + + + + + + + 57e2be6ca6b568f8f7c9b2e455e1e21f + n + 0/100 + 0/1 + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + sched-xaction + + + account + dae686a1636addc0dae1ae670701aa4a + + + credit-formula + 20.00 + + + + + + + + + + 9def659b35e85b09fe2bfade35053487 + Los pollos hermanos + y + n + n + 0 + 0 + 1 + + 2016-09-24 + + 2e9b02b5ed6fb07c7d4536bb8a03599e + + + 1 + month + + 2016-09-24 + + + + + + + + + + diff --git a/app/src/test/resources/simpleTransactionImport.xml b/app/src/test/resources/simpleTransactionImport.xml new file mode 100644 index 000000000..913e1f0ed --- /dev/null +++ b/app/src/test/resources/simpleTransactionImport.xml @@ -0,0 +1,186 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +5 +1 + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + b33c8a6160494417558fd143731fc26a + + ISO4217 + USD + + + 2016-08-23 00:00:00 +0200 + + + 2016-08-23 12:44:19 +0200 + + Kahuna Burger + + + date-posted + + 2016-08-23 + + + + + + ad2cbc774fc4e71885d17e6932448e8e + n + 1000/100 + 1000/100 + 6a7cf8267314992bdddcee56d71a3908 + + + 61d4d604bc00a59cabff4e8875d00bee + n + -1000/100 + -1000/100 + dae686a1636addc0dae1ae670701aa4a + + + + + + + + + diff --git a/app/src/test/resources/transactionWithNonDefaultSplitsImport.xml b/app/src/test/resources/transactionWithNonDefaultSplitsImport.xml new file mode 100644 index 000000000..188fd6204 --- /dev/null +++ b/app/src/test/resources/transactionWithNonDefaultSplitsImport.xml @@ -0,0 +1,222 @@ + + +1 + +fb0911dd508266db9446bc605edad3e4 + + + counter_formats + + + + options + + + Budgeting + + + + + +1 +7 +1 + + ISO4217 + USD + + currency + + + + template + template + template + template + 1 + + + Root Account + 308ade8cf0be2b0b05c5eec3114a65fa + ROOT + + ISO4217 + USD + + 100 + + + Assets + 3f44d61cb1afd201e8ea5a54ec4fbbff + ASSET + + ISO4217 + USD + + 100 + Assets + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Cash in Wallet + dae686a1636addc0dae1ae670701aa4a + CASH + + ISO4217 + USD + + 100 + Cash in Wallet + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Bank + ee139a5658a0d37507dc26284798e347 + BANK + + ISO4217 + USD + + 100 + + + color + Not Set + + + 3f44d61cb1afd201e8ea5a54ec4fbbff + + + Expenses + 9b607f63aecb1a175556676904432365 + EXPENSE + + ISO4217 + USD + + 100 + Expenses + + + placeholder + true + + + 308ade8cf0be2b0b05c5eec3114a65fa + + + Dining + 6a7cf8267314992bdddcee56d71a3908 + EXPENSE + + ISO4217 + USD + + 100 + Dining + 9b607f63aecb1a175556676904432365 + + + Imbalance-USD + 9535efccc96817a81e963dd495b1203f + BANK + + ISO4217 + USD + + 100 + 308ade8cf0be2b0b05c5eec3114a65fa + + + 042ff745a80e94e6237fb0549f6d32ae + + ISO4217 + USD + + + 2016-09-18 00:00:00 +0200 + + + 2016-09-18 19:31:41 +0200 + + Tandoori Mahal + + + date-posted + + 2016-09-18 + + + + + + c50cce06e2bf9085730821c82d0b36ca + n + 5000/100 + 5000/100 + 6a7cf8267314992bdddcee56d71a3908 + + + 4930f412665a705eedba39789b6c3a35 + tip + n + -500/100 + -500/100 + dae686a1636addc0dae1ae670701aa4a + + + b97cd9bbaa17f181d0a5b39b260dabda + n + -4500/100 + -4500/100 + ee139a5658a0d37507dc26284798e347 + + + + + + + + + diff --git a/build.gradle b/build.gradle index 8969b3cd7..8c78a1122 100644 --- a/build.gradle +++ b/build.gradle @@ -4,8 +4,10 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:2.1.2' + classpath 'com.android.tools.build:gradle:2.2.2' classpath 'io.fabric.tools:gradle:1.21.2' + classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' + classpath 'com.stanfy.spoon:spoon-gradle-plugin:1.2.2' } } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 1e6262f39..2621b5a1c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Apr 18 17:32:46 CEST 2016 +#Tue Oct 18 19:01:00 CEST 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.13-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/scripts/adb_all.bat b/scripts/adb_all.bat deleted file mode 100644 index b38971b4e..000000000 --- a/scripts/adb_all.bat +++ /dev/null @@ -1,24 +0,0 @@ -:: Inspired by Linux version of the same https://gist.github.com/christopherperry/3208109 - -@echo off -SET ARGUMENTS=%~1 - -if "%ARGUMENTS%" == "" ( - GOTO EOF -) - -SET "ARGUMENTS=%ARGUMENTS:""="%" - -SETLOCAL ENABLEDELAYEDEXPANSION -:: INSTALL ON ALL ATTACHED DEVICES :: -FOR /F "tokens=1,2 skip=1" %%A IN ('adb devices') DO ( - SET IS_DEV=%%B - if "!IS_DEV!" == "device" ( - SET SERIAL=%%A - echo "adb -s !SERIAL! %ARGUMENTS%" - call adb -s !SERIAL! %ARGUMENTS% - ) -) -ENDLOCAL - -:EOF \ No newline at end of file diff --git a/scripts/adb_all.sh b/scripts/adb_all.sh deleted file mode 100755 index fbfedd903..000000000 --- a/scripts/adb_all.sh +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/bash -# Script adb+ -# Usage -# You can run any command adb provides on all your currently connected devices -# ./adb+ is the equivalent of ./adb -s -# -# Examples -# ./adb+ version -# ./adb+ install apidemo.apk -# ./adb+ uninstall com.example.android.apis - -adb devices | while read line -do - if [ ! "$line" = "" ] && [ `echo $line | awk '{print $2}'` = "device" ] - then - device=`echo $line | awk '{print $1}'` - echo "$device $@ ..." - adb -s $device $@ - fi -done \ No newline at end of file