Skip to content

Commit 9326155

Browse files
committed
Merge branch 'hotfix/patches'
2 parents 511acfe + 55a1f50 commit 9326155

35 files changed

+674
-94
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
Change Log
22
===============================================================================
3+
Version 1.6.1 *(2015-07-08)*
4+
----------------------------
5+
* Fixed: Crash when importing some scheduled transations with custom period strings
6+
* Fixed: Crash when closing export progress dialog if an export error occurred
7+
* Fixed: Crash when creating a sub-account and changing the account type
8+
* Fixed: Crash when loading backup files with no timestamp in their name
9+
* Fixed: Crash when app is run on devices with locale es_LG
10+
* Improved: Updated betterpickers library
11+
* Improved: New dialogs for time and date when creating transactions
12+
* Improved: Added translation to Ukrainian
13+
314
Version 1.6.0 *(2015-06-20)*
415
----------------------------
516
* Feature: Scheduled backups (QIF, OFX and XML)

app/build.gradle

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ apply plugin: 'crashlytics'
55

66
def versionMajor = 1
77
def versionMinor = 6
8-
def versionPatch = 0
9-
def versionBuild = 7
8+
def versionPatch = 1
9+
def versionBuild = 0
1010

1111
def buildTime() {
1212
def df = new SimpleDateFormat("yyyyMMdd")
@@ -100,13 +100,13 @@ android {
100100
applicationId 'org.gnucash.android.devel'
101101
testApplicationId 'org.gnucash.android.devel.test'
102102
resValue "string", "app_name", "GnuCash-devel"
103-
versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev${versionBuild}_${buildTime()}"
103+
versionName "${versionMajor}.${versionMinor}.${versionPatch}-dev${versionBuild}_r${gitSha()}"
104104
resValue "string", "app_version_name", "${versionName}"
105105
}
106106

107107
beta {
108108
resValue "string", "app_name", "GnuCash - beta"
109-
versionName "${versionMajor}.${versionMinor}.${versionPatch}-beta${versionBuild}_r${gitSha()}"
109+
versionName "${versionMajor}.${versionMinor}.${versionPatch}-beta${versionBuild}"
110110
resValue "string", "app_version_name", "${versionName}"
111111
buildConfigField "boolean", "USE_CRASHLYTICS", "true"
112112
}
@@ -154,7 +154,7 @@ dependencies {
154154
compile('com.android.support:support-v4:22.1.1',
155155
'com.actionbarsherlock:actionbarsherlock:4.4.0@aar',
156156
'com.viewpagerindicator:library:2.4.1@aar',
157-
'com.doomonafireball.betterpickers:library:1.5.2',
157+
'com.doomonafireball.betterpickers:library:1.6.0',
158158
'com.commonsware.cwac:merge:1.1.+',
159159
'com.github.PhilJay:MPAndroidChart:v2.1.0',
160160
'joda-time:joda-time:2.7',

app/src/androidTest/java/org/gnucash/android/test/ui/AccountsActivityTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.gnucash.android.db.SplitsDbAdapter;
3636
import org.gnucash.android.db.TransactionsDbAdapter;
3737
import org.gnucash.android.model.Account;
38+
import org.gnucash.android.model.AccountType;
3839
import org.gnucash.android.model.Money;
3940
import org.gnucash.android.receivers.AccountCreator;
4041
import org.gnucash.android.ui.account.AccountsActivity;
@@ -47,19 +48,24 @@
4748
import java.util.Currency;
4849
import java.util.List;
4950

51+
import static android.support.test.espresso.Espresso.onData;
5052
import static android.support.test.espresso.Espresso.onView;
5153
import static android.support.test.espresso.action.ViewActions.clearText;
5254
import static android.support.test.espresso.action.ViewActions.click;
5355
import static android.support.test.espresso.action.ViewActions.longClick;
5456
import static android.support.test.espresso.action.ViewActions.scrollTo;
57+
import static android.support.test.espresso.action.ViewActions.swipeRight;
5558
import static android.support.test.espresso.action.ViewActions.typeText;
5659
import static android.support.test.espresso.assertion.ViewAssertions.matches;
60+
import static android.support.test.espresso.matcher.ViewMatchers.isChecked;
5761
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
5862
import static android.support.test.espresso.matcher.ViewMatchers.isNotChecked;
5963
import static android.support.test.espresso.matcher.ViewMatchers.withId;
6064
import static android.support.test.espresso.matcher.ViewMatchers.withText;
6165
import static org.assertj.core.api.Assertions.assertThat;
6266
import static org.hamcrest.Matchers.allOf;
67+
import static org.hamcrest.Matchers.instanceOf;
68+
import static org.hamcrest.Matchers.is;
6369
import static org.hamcrest.Matchers.not;
6470

6571
@RunWith(AndroidJUnit4.class)
@@ -213,6 +219,31 @@ public void testChangeParentAccount() {
213219
assertThat(DUMMY_ACCOUNT_UID).isEqualTo(parentUID);
214220
}
215221

222+
/**
223+
* When creating a sub-account (starting from within another account), if we change the account
224+
* type to another type with no accounts of that type, then the parent account list should be hidden.
225+
* The account which is then created is not a sub-account, but rather a top-level account
226+
*/
227+
@Test
228+
public void shouldHideParentAccountViewWhenNoParentsExist(){
229+
onView(withText(DUMMY_ACCOUNT_NAME)).perform(click());
230+
onView(withId(R.id.fragment_transaction_list)).perform(swipeRight());
231+
onView(withText(R.string.label_create_account)).check(matches(isDisplayed())).perform(click());
232+
sleep(1000);
233+
onView(withId(R.id.checkbox_parent_account)).check(matches(allOf(isChecked())));
234+
onView(withId(R.id.input_account_name)).perform(typeText("Trading account"));
235+
onView(withId(R.id.input_account_type_spinner)).perform(click());
236+
onData(allOf(is(instanceOf(String.class)), is(AccountType.TRADING.name()))).perform(click());
237+
238+
onView(withId(R.id.layout_parent_account)).check(matches(not(isDisplayed())));
239+
onView(withId(R.id.menu_save)).perform(click());
240+
241+
//no sub-accounts
242+
assertThat(mAccountsDbAdapter.getSubAccountCount(DUMMY_ACCOUNT_UID)).isEqualTo(0);
243+
assertThat(mAccountsDbAdapter.getSubAccountCount(mAccountsDbAdapter.getOrCreateGnuCashRootAccountUID())).isEqualTo(2);
244+
assertThat(mAccountsDbAdapter.getSimpleAccountList()).extracting("mAccountType").contains(AccountType.TRADING);
245+
}
246+
216247
@Test
217248
public void testEditAccount(){
218249
String editedAccountName = "Edited Account";

app/src/androidTest/java/org/gnucash/android/test/ui/TransactionsActivityTest.java

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
package org.gnucash.android.test.ui;
1818

19-
import android.app.Fragment;
2019
import android.content.ContentValues;
2120
import android.content.Intent;
2221
import android.content.SharedPreferences;
@@ -28,8 +27,6 @@
2827
import android.support.test.runner.AndroidJUnit4;
2928
import android.test.ActivityInstrumentationTestCase2;
3029
import android.util.Log;
31-
import android.widget.LinearLayout;
32-
import android.widget.Spinner;
3330

3431
import org.gnucash.android.R;
3532
import org.gnucash.android.db.AccountsDbAdapter;
@@ -58,7 +55,6 @@
5855
import java.util.List;
5956
import java.util.Locale;
6057

61-
import static android.support.test.espresso.Espresso.onData;
6258
import static android.support.test.espresso.Espresso.onView;
6359
import static android.support.test.espresso.action.ViewActions.clearText;
6460
import static android.support.test.espresso.action.ViewActions.click;
@@ -69,15 +65,10 @@
6965
import static android.support.test.espresso.matcher.ViewMatchers.hasDescendant;
7066
import static android.support.test.espresso.matcher.ViewMatchers.isChecked;
7167
import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed;
72-
import static android.support.test.espresso.matcher.ViewMatchers.isNotChecked;
73-
import static android.support.test.espresso.matcher.ViewMatchers.withChild;
7468
import static android.support.test.espresso.matcher.ViewMatchers.withId;
75-
import static android.support.test.espresso.matcher.ViewMatchers.withSpinnerText;
7669
import static android.support.test.espresso.matcher.ViewMatchers.withText;
77-
import static org.assertj.android.api.Assertions.assertThat;
7870
import static org.assertj.core.api.Assertions.assertThat;
7971
import static org.hamcrest.Matchers.allOf;
80-
import static org.hamcrest.Matchers.instanceOf;
8172
import static org.hamcrest.Matchers.is;
8273
import static org.hamcrest.Matchers.not;
8374

@@ -191,14 +182,26 @@ public void testAddTransactionShouldRequireAmount(){
191182
.perform(typeText("Lunch"));
192183

193184
onView(withId(R.id.menu_save)).perform(click());
194-
185+
sleep(500);
195186
assertToastDisplayed(R.string.toast_transanction_amount_required);
196187

197188
int afterCount = mTransactionsDbAdapter.getTransactionsCount(DUMMY_ACCOUNT_UID);
198189
assertThat(afterCount).isEqualTo(beforeCount);
199190

200191
}
201192

193+
/**
194+
* Sleep the thread for a specified period
195+
* @param millis Duration to sleep in milliseconds
196+
*/
197+
private void sleep(long millis) {
198+
try {
199+
Thread.sleep(millis);
200+
} catch (InterruptedException e) {
201+
e.printStackTrace();
202+
}
203+
}
204+
202205
/**
203206
* Checks that a specific toast message is displayed
204207
* @param toastString
@@ -219,7 +222,8 @@ private void validateEditTransactionFields(Transaction transaction){
219222
formatter.setMinimumFractionDigits(2);
220223
formatter.setMaximumFractionDigits(2);
221224
onView(withId(R.id.input_transaction_amount)).check(matches(withText(formatter.format(balance.asDouble()))));
222-
225+
onView(withId(R.id.input_date)).check(matches(withText(TransactionFormFragment.DATE_FORMATTER.format(transaction.getTimeMillis()))));
226+
onView(withId(R.id.input_time)).check(matches(withText(TransactionFormFragment.TIME_FORMATTER.format(transaction.getTimeMillis()))));
223227
onView(withId(R.id.input_description)).check(matches(withText(transaction.getNote())));
224228

225229
validateTimeInput(transaction.getTimeMillis());

app/src/main/java/org/gnucash/android/app/GnuCashApplication.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,13 +158,18 @@ public static boolean shouldSaveOpeningBalances(boolean defaultValue){
158158
*
159159
* @return Default currency code string for the application
160160
*/
161-
public static String getDefaultCurrency(){
161+
public static String getDefaultCurrencyCode(){
162162
Locale locale = Locale.getDefault();
163163
//sometimes the locale en_UK is returned which causes a crash with Currency
164164
if (locale.getCountry().equals("UK")) {
165165
locale = new Locale(locale.getLanguage(), "GB");
166166
}
167167

168+
//for unsupported locale es_LG
169+
if (locale.getCountry().equals("LG")){
170+
locale = new Locale(locale.getLanguage(), "ES");
171+
}
172+
168173
String currencyCode = "USD"; //start with USD as the default
169174
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
170175
try { //there are some strange locales out there

app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -813,7 +813,7 @@ private Money computeBalance(String accountUID, long startTimestamp, long endTim
813813
* @return the absolute balance of account list
814814
*/
815815
public Money getAccountsBalance(List<String> accountUIDList, long startTimestamp, long endTimestamp) {
816-
String currencyCode = GnuCashApplication.getDefaultCurrency();
816+
String currencyCode = GnuCashApplication.getDefaultCurrencyCode();
817817
Money balance = Money.createZeroInstance(currencyCode);
818818

819819
SplitsDbAdapter splitsDbAdapter = SplitsDbAdapter.getInstance();

app/src/main/java/org/gnucash/android/db/DatabaseAdapter.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ public long getID(@NonNull String uid){
286286
* Returns the string unique ID (GUID) of a record in the database
287287
* @param id long database record ID
288288
* @return GUID of the record
289+
* @throws IllegalArgumentException if the record ID does not exist in the database
289290
*/
290291
public String getUID(long id){
291292
Cursor cursor = mDb.query(mTableName,

app/src/main/java/org/gnucash/android/export/ExportAsyncTask.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.gnucash.android.export.xml.GncXmlExporter;
5656
import org.gnucash.android.model.Transaction;
5757
import org.gnucash.android.ui.account.AccountsActivity;
58+
import org.gnucash.android.ui.account.AccountsListFragment;
5859
import org.gnucash.android.ui.settings.SettingsActivity;
5960
import org.gnucash.android.ui.transaction.TransactionsActivity;
6061

@@ -233,7 +234,9 @@ protected void onPostExecute(Boolean exportResult) {
233234

234235
//now refresh the respective views
235236
if (mContext instanceof AccountsActivity){
236-
((AccountsActivity) mContext).getCurrentAccountListFragment().refresh();
237+
AccountsListFragment fragment = ((AccountsActivity) mContext).getCurrentAccountListFragment();
238+
if (fragment != null)
239+
fragment.refresh();
237240
}
238241
if (mContext instanceof TransactionsActivity){
239242
((TransactionsActivity) mContext).refresh();

app/src/main/java/org/gnucash/android/export/Exporter.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ public static String buildExportFilename(ExportFormat format) {
118118
public static long getExportTime(String filename){
119119
String[] tokens = filename.split("_");
120120
long timeMillis = 0;
121+
if (tokens.length < 2){
122+
return timeMillis;
123+
}
121124
try {
122125
Date date = EXPORT_FILENAME_DATE_FORMAT.parse(tokens[0] + "_" + tokens[1]);
123126
timeMillis = date.getTime();

app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,11 @@ public class GncXmlHandler extends DefaultHandler {
191191
*/
192192
boolean mIgnoreTemplateTransaction = true;
193193

194+
/**
195+
* Flag which notifies the handler to ignore a scheduled action because some error occurred during parsing
196+
*/
197+
boolean mIgnoreScheduledAction = false;
198+
194199
/**
195200
* Used for parsing old backup files where recurrence was saved inside the transaction.
196201
* Newer backup files will not require this
@@ -547,9 +552,16 @@ public void endElement(String uri, String localName, String qualifiedName) throw
547552
mRecurrenceMultiplier = Integer.parseInt(characterString);
548553
break;
549554
case GncXmlHelper.TAG_RX_PERIOD_TYPE:
550-
PeriodType periodType = PeriodType.valueOf(characterString.toUpperCase());
551-
periodType.setMultiplier(mRecurrenceMultiplier);
552-
mScheduledAction.setPeriod(periodType);
555+
try {
556+
PeriodType periodType = PeriodType.valueOf(characterString.toUpperCase());
557+
periodType.setMultiplier(mRecurrenceMultiplier);
558+
mScheduledAction.setPeriod(periodType);
559+
} catch (IllegalArgumentException ex){ //the period type constant is not supported
560+
String msg = "Unsupported period constant: " + characterString;
561+
Log.e(LOG_TAG, msg);
562+
Crashlytics.logException(ex);
563+
mIgnoreScheduledAction = true;
564+
}
553565
break;
554566
case GncXmlHelper.TAG_GDATE:
555567
try {
@@ -589,11 +601,13 @@ public void endElement(String uri, String localName, String qualifiedName) throw
589601
}
590602
break;
591603
case GncXmlHelper.TAG_SCHEDULED_ACTION:
592-
if (mScheduledAction.getActionUID() != null)
604+
if (mScheduledAction.getActionUID() != null && !mIgnoreScheduledAction) {
593605
mScheduledActionsList.add(mScheduledAction);
594-
int count = generateMissedScheduledTransactions(mScheduledAction);
595-
Log.i(LOG_TAG, String.format("Generated %d transactions from scheduled action", count));
606+
int count = generateMissedScheduledTransactions(mScheduledAction);
607+
Log.i(LOG_TAG, String.format("Generated %d transactions from scheduled action", count));
608+
}
596609
mRecurrenceMultiplier = 1; //reset it, even though it will be parsed from XML each time
610+
mIgnoreScheduledAction = false;
597611
break;
598612
}
599613

0 commit comments

Comments
 (0)