From 670724e03f05ec387994697c5980cb66252d8a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Sun, 27 Mar 2016 14:32:47 +0200 Subject: [PATCH 01/15] Simplify code by not returning null from Account.getDescription(). --- .../main/java/org/gnucash/android/db/AccountsDbAdapter.java | 6 +++--- app/src/main/java/org/gnucash/android/model/Account.java | 5 +++-- .../org/gnucash/android/ui/account/AccountFormFragment.java | 4 +--- .../org/gnucash/android/test/unit/model/AccountTest.java | 6 ++++++ 4 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java index 07aad7a70..52b95b1c5 100644 --- a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java @@ -173,8 +173,7 @@ protected SQLiteStatement compileReplaceStatement(@NonNull final Account account mReplaceStatement.clearBindings(); mReplaceStatement.bindString(1, account.getUID()); mReplaceStatement.bindString(2, account.getName()); - if (account.getDescription() != null) - mReplaceStatement.bindString(3, account.getDescription()); + mReplaceStatement.bindString(3, account.getDescription()); mReplaceStatement.bindString(4, account.getAccountType().name()); mReplaceStatement.bindString(5, account.getCurrency().getCurrencyCode()); if (account.getColorHexCode() != null) { @@ -407,7 +406,8 @@ private Account buildSimpleAccountInstance(Cursor c) { Account account = new Account(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_NAME))); populateBaseModelAttributes(c, account); - account.setDescription(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_DESCRIPTION))); + String description = c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_DESCRIPTION)); + account.setDescription(description == null ? "" : description); account.setParentUID(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_PARENT_ACCOUNT_UID))); account.setAccountType(AccountType.valueOf(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_TYPE)))); Currency currency = Currency.getInstance(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_CURRENCY))); diff --git a/app/src/main/java/org/gnucash/android/model/Account.java b/app/src/main/java/org/gnucash/android/model/Account.java index 6df050366..b5d7066b7 100644 --- a/app/src/main/java/org/gnucash/android/model/Account.java +++ b/app/src/main/java/org/gnucash/android/model/Account.java @@ -18,6 +18,7 @@ import android.preference.PreferenceManager; +import android.support.annotation.NonNull; import org.gnucash.android.BuildConfig; import org.gnucash.android.app.GnuCashApplication; @@ -88,7 +89,7 @@ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } /** * Account description */ - private String mDescription; + private String mDescription = ""; /** * Currency used by transactions in this account @@ -222,7 +223,7 @@ public String getDescription() { * Sets the account mDescription * @param description String mDescription */ - public void setDescription(String description) { + public void setDescription(@NonNull String description) { this.mDescription = description; } diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java index 40641de17..4e77e94d8 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java @@ -395,9 +395,7 @@ private void initializeViewsWithAccount(Account account){ mNameEditText.setText(account.getName()); mNameEditText.setSelection(mNameEditText.getText().length()); - - if (account.getDescription() != null) - mDescriptionEditText.setText(account.getDescription()); + mDescriptionEditText.setText(account.getDescription()); if (mUseDoubleEntry) { if (account.getDefaultTransferAccountUID() != null) { diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java index 1c378c789..182854f02 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java @@ -103,4 +103,10 @@ public void settingCurrencyCode_shouldNotSetCommodity(){ assertThat(account.getCommodity()).isEqualTo(Commodity.EUR); assertThat(account.getCurrency()).isEqualTo(Currency.getInstance("USD")); } + + @Test + public void newInstance_shouldHaveNonNullDescription() { + Account account = new Account("Test account"); + assertThat(account.getDescription()).isEqualTo(""); + } } From 6d31dc81df8745a58a6218f074902296266233b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Sun, 27 Mar 2016 19:25:21 +0200 Subject: [PATCH 02/15] Simplify code by not returning null from Account.getColorHexCode(). --- .../gnucash/android/db/AccountsDbAdapter.java | 6 +++-- .../org/gnucash/android/model/Account.java | 15 +++++++----- .../ui/account/AccountFormFragment.java | 23 +++---------------- .../android/ui/report/BarChartFragment.java | 4 +--- .../android/ui/report/PieChartFragment.java | 2 +- .../ui/report/ReportSummaryFragment.java | 4 +--- .../android/test/unit/model/AccountTest.java | 3 ++- 7 files changed, 21 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java index 52b95b1c5..a7fcd39e6 100644 --- a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java @@ -176,7 +176,7 @@ protected SQLiteStatement compileReplaceStatement(@NonNull final Account account mReplaceStatement.bindString(3, account.getDescription()); mReplaceStatement.bindString(4, account.getAccountType().name()); mReplaceStatement.bindString(5, account.getCurrency().getCurrencyCode()); - if (account.getColorHexCode() != null) { + if (account.getColorHexCode() != Account.DEFAULT_COLOR) { mReplaceStatement.bindString(6, account.getColorHexCode()); } mReplaceStatement.bindLong(7, account.isFavorite() ? 1 : 0); @@ -414,7 +414,9 @@ private Account buildSimpleAccountInstance(Cursor c) { account.setCommodity(CommoditiesDbAdapter.getInstance().getCommodity(currency.getCurrencyCode())); account.setPlaceHolderFlag(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_PLACEHOLDER)) == 1); account.setDefaultTransferAccountUID(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID))); - account.setColorCode(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_COLOR_CODE))); + String color = c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_COLOR_CODE)); + if (color != null) + account.setColorCode(color); account.setFavorite(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_FAVORITE)) == 1); account.setFullName(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_FULL_NAME))); account.setHidden(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_HIDDEN)) == 1); diff --git a/app/src/main/java/org/gnucash/android/model/Account.java b/app/src/main/java/org/gnucash/android/model/Account.java index b5d7066b7..63e69f0a4 100644 --- a/app/src/main/java/org/gnucash/android/model/Account.java +++ b/app/src/main/java/org/gnucash/android/model/Account.java @@ -17,6 +17,7 @@ package org.gnucash.android.model; +import android.graphics.Color; import android.preference.PreferenceManager; import android.support.annotation.NonNull; @@ -70,7 +71,12 @@ public class Account extends BaseModel{ //TODO: Allow use of #aarrggbb format as well public static final String COLOR_HEX_REGEX = "^#(?:[0-9a-fA-F]{3}){1,2}$"; - /** + /** + * Default color, if not set explicitly through {@link #setColorCode(String)}. + */ + public static final String DEFAULT_COLOR = "#cccccc"; // Color.LT_GRAY + + /** * Accounts types which are used by the OFX standard */ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } @@ -133,7 +139,7 @@ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } /** * Account color field in hex format #rrggbb */ - private String mColorCode; + private String mColorCode = DEFAULT_COLOR; /** * Flag which marks this account as a favorite account @@ -306,10 +312,7 @@ public String getColorHexCode() { * @param colorCode Color code to be set in the format #rrggbb or #rgb * @throws java.lang.IllegalArgumentException if the color code is not properly formatted */ - public void setColorCode(String colorCode) { - if (colorCode == null) - return; - + public void setColorCode(@NonNull String colorCode) { if (!Pattern.matches(COLOR_HEX_REGEX, colorCode)) throw new IllegalArgumentException("Invalid color hex code: " + colorCode); diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java index 4e77e94d8..0a29dbd55 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java @@ -203,10 +203,7 @@ public class AccountFormFragment extends Fragment { */ private boolean mUseDoubleEntry; - /** - * Default to transparent - */ - private String mSelectedColor = null; + private String mSelectedColor = Account.DEFAULT_COLOR; /** * Trigger for color picker dialog @@ -417,7 +414,7 @@ private void initializeViewsWithAccount(Account account){ } mPlaceholderCheckBox.setChecked(account.isPlaceholderAccount()); - initializeColorSquarePreview(account.getColorHexCode()); + mColorSquare.setBackgroundColor(Color.parseColor(account.getColorHexCode())); setAccountTypeSelection(account.getAccountType()); } @@ -440,17 +437,6 @@ private void initializeViews(){ } - /** - * Initializes the preview of the color picker (color square) to the specified color - * @param colorHex Color of the format #rgb or #rrggbb - */ - private void initializeColorSquarePreview(String colorHex){ - if (colorHex != null) - mColorSquare.setBackgroundColor(Color.parseColor(colorHex)); - else - mColorSquare.setBackgroundColor(Color.LTGRAY); - } - /** * Selects the corresponding account type in the spinner * @param accountType AccountType to be set @@ -549,10 +535,7 @@ private void showColorPickerDialog(){ FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); int currentColor = Color.LTGRAY; if (mAccount != null){ - String accountColor = mAccount.getColorHexCode(); - if (accountColor != null){ - currentColor = Color.parseColor(accountColor); - } + currentColor = Color.parseColor(mAccount.getColorHexCode()); } ColorPickerDialog colorPickerDialogFragment = ColorPickerDialog.newInstance( diff --git a/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java index 0cd2f3dd9..21118404c 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java @@ -229,9 +229,7 @@ private BarData getData() { if (!accountToColorMap.containsKey(account.getUID())) { Integer color; if (mUseAccountColor) { - color = (account.getColorHexCode() != null) - ? Color.parseColor(account.getColorHexCode()) - : COLORS[accountToColorMap.size() % COLORS.length]; + color = Color.parseColor(account.getColorHexCode()); } else { color = COLORS[accountToColorMap.size() % COLORS.length]; } diff --git a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java index f4b4ea5e9..1c182d7e4 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java @@ -199,7 +199,7 @@ private PieData getData() { mReportStartTime, mReportEndTime).asDouble(); if (balance > 0) { dataSet.addEntry(new Entry((float) balance, dataSet.getEntryCount())); - colors.add(mUseAccountColor && account.getColorHexCode() != null + colors.add(mUseAccountColor ? Color.parseColor(account.getColorHexCode()) : ReportsActivity.COLORS[(dataSet.getEntryCount() - 1) % ReportsActivity.COLORS.length]); labels.add(account.getName()); diff --git a/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java b/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java index 88d2257a7..815cd013d 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java @@ -200,9 +200,7 @@ private PieData getData() { Collections.singletonList(account.getUID()), start, end).asDouble(); if (balance > 0) { dataSet.addEntry(new Entry((float) balance, dataSet.getEntryCount())); - colors.add(account.getColorHexCode() != null - ? Color.parseColor(account.getColorHexCode()) - : ReportsActivity.COLORS[(dataSet.getEntryCount() - 1) % ReportsActivity.COLORS.length]); + colors.add(Color.parseColor(account.getColorHexCode())); labels.add(account.getName()); } } diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java index 182854f02..359af5361 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java @@ -105,8 +105,9 @@ public void settingCurrencyCode_shouldNotSetCommodity(){ } @Test - public void newInstance_shouldHaveNonNullDescription() { + public void newInstance_shouldReturnNonNullValues() { Account account = new Account("Test account"); assertThat(account.getDescription()).isEqualTo(""); + assertThat(account.getColorHexCode()).isEqualTo(Account.DEFAULT_COLOR); } } From 17d64d5e9ec8f20bb5681aad1dae68462d1715cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Sat, 2 Apr 2016 14:11:41 +0200 Subject: [PATCH 03/15] Store account color as an int. All uses of Account.getColorHexCode() were being converted to an int with Color.parseColor(). --- .../gnucash/android/db/AccountsDbAdapter.java | 12 ++++--- .../android/importer/GncXmlHandler.java | 2 +- .../org/gnucash/android/model/Account.java | 36 ++++++++++++------- .../ui/account/AccountFormFragment.java | 10 +++--- .../android/ui/report/BarChartFragment.java | 2 +- .../android/ui/report/PieChartFragment.java | 2 +- .../ui/report/ReportSummaryFragment.java | 3 +- .../android/test/unit/model/AccountTest.java | 12 +++++-- 8 files changed, 50 insertions(+), 29 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java index a7fcd39e6..d867ee2e9 100644 --- a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java @@ -176,8 +176,8 @@ protected SQLiteStatement compileReplaceStatement(@NonNull final Account account mReplaceStatement.bindString(3, account.getDescription()); mReplaceStatement.bindString(4, account.getAccountType().name()); mReplaceStatement.bindString(5, account.getCurrency().getCurrencyCode()); - if (account.getColorHexCode() != Account.DEFAULT_COLOR) { - mReplaceStatement.bindString(6, account.getColorHexCode()); + if (account.getColor() != Account.DEFAULT_COLOR) { + mReplaceStatement.bindString(6, convertToRGBHexString(account.getColor())); } mReplaceStatement.bindLong(7, account.isFavorite() ? 1 : 0); mReplaceStatement.bindString(8, account.getFullName()); @@ -205,6 +205,10 @@ protected SQLiteStatement compileReplaceStatement(@NonNull final Account account return mReplaceStatement; } + private String convertToRGBHexString(int color) { + return String.format("#%06X", (0xFFFFFF & color)); + } + /** * Marks all transactions for a given account as exported * @param accountUID Unique ID of the record to be marked as exported @@ -416,7 +420,7 @@ private Account buildSimpleAccountInstance(Cursor c) { account.setDefaultTransferAccountUID(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_DEFAULT_TRANSFER_ACCOUNT_UID))); String color = c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_COLOR_CODE)); if (color != null) - account.setColorCode(color); + account.setColor(color); account.setFavorite(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_FAVORITE)) == 1); account.setFullName(c.getString(c.getColumnIndexOrThrow(AccountEntry.COLUMN_FULL_NAME))); account.setHidden(c.getInt(c.getColumnIndexOrThrow(AccountEntry.COLUMN_HIDDEN)) == 1); @@ -563,7 +567,7 @@ public String getOrCreateImbalanceAccountUID(Currency currency){ account.setAccountType(AccountType.BANK); account.setParentUID(getOrCreateGnuCashRootAccountUID()); account.setHidden(!GnuCashApplication.isDoubleEntryEnabled()); - account.setColorCode("#964B00"); + account.setColor("#964B00"); addRecord(account); uid = account.getUID(); } 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 b4ac1235f..c6872f938 100644 --- a/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java +++ b/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java @@ -467,7 +467,7 @@ public void endElement(String uri, String localName, String qualifiedName) throw color = "#" + color.replaceAll(".(.)?", "$1").replace("null", ""); try { if (mAccount != null) - mAccount.setColorCode(color); + mAccount.setColor(color); } catch (IllegalArgumentException ex) { //sometimes the color entry in the account file is "Not set" instead of just blank. So catch! Log.e(LOG_TAG, "Invalid color code '" + color + "' for account " + mAccount.getName()); diff --git a/app/src/main/java/org/gnucash/android/model/Account.java b/app/src/main/java/org/gnucash/android/model/Account.java index 63e69f0a4..0dd879c61 100644 --- a/app/src/main/java/org/gnucash/android/model/Account.java +++ b/app/src/main/java/org/gnucash/android/model/Account.java @@ -18,12 +18,9 @@ import android.graphics.Color; -import android.preference.PreferenceManager; import android.support.annotation.NonNull; import org.gnucash.android.BuildConfig; -import org.gnucash.android.app.GnuCashApplication; -import org.gnucash.android.export.Exporter; import org.gnucash.android.export.ofx.OfxHelper; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -72,9 +69,10 @@ public class Account extends BaseModel{ public static final String COLOR_HEX_REGEX = "^#(?:[0-9a-fA-F]{3}){1,2}$"; /** - * Default color, if not set explicitly through {@link #setColorCode(String)}. + * Default color, if not set explicitly through {@link #setColor(String)}. */ - public static final String DEFAULT_COLOR = "#cccccc"; // Color.LT_GRAY + // TODO: get it from a theme value? + public static final int DEFAULT_COLOR = Color.LTGRAY; /** * Accounts types which are used by the OFX standard @@ -139,7 +137,7 @@ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } /** * Account color field in hex format #rrggbb */ - private String mColorCode = DEFAULT_COLOR; + private int mColor = DEFAULT_COLOR; /** * Flag which marks this account as a favorite account @@ -300,23 +298,35 @@ public Money getBalance(){ } /** - * Returns the color code of the account in the format #rrggbb - * @return Color code of the account + * Returns the color of the account. + * @return Color of the account as an int as returned by {@link Color}. */ - public String getColorHexCode() { - return mColorCode; + public int getColor() { + return mColor; } + /** + * Sets the color of the account. + * @param color Color as an int as returned by {@link Color}. + * @throws java.lang.IllegalArgumentException if the color is transparent, + * which is not supported. + */ + public void setColor(int color) { + if (Color.alpha(color) < 255) + throw new IllegalArgumentException("Transparent colors are not supported: " + color); + mColor = color; + } + /** - * Sets the color code of the account. + * Sets the color of the account. * @param colorCode Color code to be set in the format #rrggbb or #rgb * @throws java.lang.IllegalArgumentException if the color code is not properly formatted */ - public void setColorCode(@NonNull String colorCode) { + public void setColor(@NonNull String colorCode) { if (!Pattern.matches(COLOR_HEX_REGEX, colorCode)) throw new IllegalArgumentException("Invalid color hex code: " + colorCode); - this.mColorCode = colorCode; + setColor(Color.parseColor(colorCode)); } /** diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java index 0a29dbd55..a29b90816 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java @@ -203,7 +203,7 @@ public class AccountFormFragment extends Fragment { */ private boolean mUseDoubleEntry; - private String mSelectedColor = Account.DEFAULT_COLOR; + private int mSelectedColor = Account.DEFAULT_COLOR; /** * Trigger for color picker dialog @@ -214,7 +214,7 @@ public class AccountFormFragment extends Fragment { @Override public void onColorSelected(int color) { mColorSquare.setBackgroundColor(color); - mSelectedColor = String.format("#%06X", (0xFFFFFF & color)); + mSelectedColor = color; } }; @@ -414,7 +414,7 @@ private void initializeViewsWithAccount(Account account){ } mPlaceholderCheckBox.setChecked(account.isPlaceholderAccount()); - mColorSquare.setBackgroundColor(Color.parseColor(account.getColorHexCode())); + mColorSquare.setBackgroundColor(account.getColor()); setAccountTypeSelection(account.getAccountType()); } @@ -535,7 +535,7 @@ private void showColorPickerDialog(){ FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); int currentColor = Color.LTGRAY; if (mAccount != null){ - currentColor = Color.parseColor(mAccount.getColorHexCode()); + currentColor = mAccount.getColor(); } ColorPickerDialog colorPickerDialogFragment = ColorPickerDialog.newInstance( @@ -757,7 +757,7 @@ private void saveAccount() { mAccount.setDescription(mDescriptionEditText.getText().toString()); mAccount.setPlaceHolderFlag(mPlaceholderCheckBox.isChecked()); - mAccount.setColorCode(mSelectedColor); + mAccount.setColor(mSelectedColor); long newParentAccountId; String newParentAccountUID; diff --git a/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java index 21118404c..3aa0502c6 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/BarChartFragment.java @@ -229,7 +229,7 @@ private BarData getData() { if (!accountToColorMap.containsKey(account.getUID())) { Integer color; if (mUseAccountColor) { - color = Color.parseColor(account.getColorHexCode()); + color = account.getColor(); } else { color = COLORS[accountToColorMap.size() % COLORS.length]; } diff --git a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java index 1c182d7e4..ac1080cf5 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java @@ -200,7 +200,7 @@ private PieData getData() { if (balance > 0) { dataSet.addEntry(new Entry((float) balance, dataSet.getEntryCount())); colors.add(mUseAccountColor - ? Color.parseColor(account.getColorHexCode()) + ? account.getColor() : ReportsActivity.COLORS[(dataSet.getEntryCount() - 1) % ReportsActivity.COLORS.length]); labels.add(account.getName()); } diff --git a/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java b/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java index 815cd013d..a84c02ac3 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/ReportSummaryFragment.java @@ -16,7 +16,6 @@ package org.gnucash.android.ui.report; import android.content.res.ColorStateList; -import android.graphics.Color; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; @@ -200,7 +199,7 @@ private PieData getData() { Collections.singletonList(account.getUID()), start, end).asDouble(); if (balance > 0) { dataSet.addEntry(new Entry((float) balance, dataSet.getEntryCount())); - colors.add(Color.parseColor(account.getColorHexCode())); + colors.add(account.getColor()); labels.add(account.getName()); } } diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java index 359af5361..a172e361d 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/AccountTest.java @@ -15,6 +15,8 @@ */ package org.gnucash.android.test.unit.model; +import android.graphics.Color; + import org.gnucash.android.BuildConfig; import org.gnucash.android.model.Account; import org.gnucash.android.model.Commodity; @@ -66,7 +68,13 @@ public void testTransactionsHaveSameCurrencyAsAccount(){ @Test(expected = IllegalArgumentException.class) public void testSetInvalidColorCode(){ Account account = new Account("Test"); - account.setColorCode("443859"); + account.setColor("443859"); + } + + @Test(expected = IllegalArgumentException.class) + public void testSetColorWithAlphaComponent(){ + Account account = new Account("Test"); + account.setColor(Color.parseColor("#aa112233")); } @Test @@ -108,6 +116,6 @@ public void settingCurrencyCode_shouldNotSetCommodity(){ public void newInstance_shouldReturnNonNullValues() { Account account = new Account("Test account"); assertThat(account.getDescription()).isEqualTo(""); - assertThat(account.getColorHexCode()).isEqualTo(Account.DEFAULT_COLOR); + assertThat(account.getColor()).isEqualTo(Account.DEFAULT_COLOR); } } From ae357246e929409bde48a2837e5552d4c3428cd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Sun, 3 Apr 2016 21:33:20 +0200 Subject: [PATCH 04/15] Remove support for #rgb format when setting the account color. It's never used. #rrggbb is used instead. --- .../android/importer/GncXmlHandler.java | 20 ++++++++- .../org/gnucash/android/model/Account.java | 44 +++++-------------- 2 files changed, 31 insertions(+), 33 deletions(-) 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 c6872f938..3a03b7375 100644 --- a/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java +++ b/app/src/main/java/org/gnucash/android/importer/GncXmlHandler.java @@ -75,6 +75,24 @@ public class GncXmlHandler extends DefaultHandler { */ private static final String LOG_TAG = "GnuCashAccountImporter"; + /* + ^ anchor for start of string + # the literal # + ( start of group + ?: indicate a non-capturing group that doesn't generate back-references + [0-9a-fA-F] hexadecimal digit + {3} three times + ) end of group + {2} repeat twice + $ anchor for end of string + */ + /** + * Regular expression for validating color code strings. + * Accepts #rgb and #rrggbb + */ + //TODO: Allow use of #aarrggbb format as well + public static final String ACCOUNT_COLOR_HEX_REGEX = "^#(?:[0-9a-fA-F]{3}){2}$"; + /** * Adapter for saving the imported accounts */ @@ -463,7 +481,7 @@ public void endElement(String uri, String localName, String qualifiedName) throw //so we trim the last digit in each block, doesn't affect the color much if (!color.equals("Not Set")) { // avoid known exception, printStackTrace is very time consuming - if (!Pattern.matches(Account.COLOR_HEX_REGEX, color)) + if (!Pattern.matches(ACCOUNT_COLOR_HEX_REGEX, color)) color = "#" + color.replaceAll(".(.)?", "$1").replace("null", ""); try { if (mAccount != null) diff --git a/app/src/main/java/org/gnucash/android/model/Account.java b/app/src/main/java/org/gnucash/android/model/Account.java index 0dd879c61..e89c9d47c 100644 --- a/app/src/main/java/org/gnucash/android/model/Account.java +++ b/app/src/main/java/org/gnucash/android/model/Account.java @@ -29,7 +29,6 @@ import java.util.ArrayList; import java.util.Currency; import java.util.List; -import java.util.regex.Pattern; /** * An account represents a transaction account in with {@link Transaction}s may be recorded @@ -50,24 +49,6 @@ public class Account extends BaseModel{ */ public static final String MIME_TYPE = "vnd.android.cursor.item/vnd." + BuildConfig.APPLICATION_ID + ".account"; - /* - ^ anchor for start of string - # the literal # - ( start of group - ?: indicate a non-capturing group that doesn't generate back-references - [0-9a-fA-F] hexadecimal digit - {3} three times - ) end of group - {1,2} repeat either once or twice - $ anchor for end of string - */ - /** - * Regular expression for validating color code strings. - * Accepts #rgb and #rrggbb - */ - //TODO: Allow use of #aarrggbb format as well - public static final String COLOR_HEX_REGEX = "^#(?:[0-9a-fA-F]{3}){1,2}$"; - /** * Default color, if not set explicitly through {@link #setColor(String)}. */ @@ -111,7 +92,7 @@ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } * Defaults to {@link AccountType#CASH} */ private AccountType mAccountType = AccountType.CASH; - + /** * List of transactions in this account */ @@ -153,13 +134,13 @@ public enum OfxAccountType {CHECKING, SAVINGS, MONEYMRKT, CREDITLINE } * An extra key for passing the currency code (according ISO 4217) in an intent */ public static final String EXTRA_CURRENCY_CODE = "org.gnucash.android.extra.currency_code"; - + /** - * Extra key for passing the unique ID of the parent account when creating a + * Extra key for passing the unique ID of the parent account when creating a * new account using Intents */ public static final String EXTRA_PARENT_UID = "org.gnucash.android.extra.parent_uid"; - + /** * Constructor * Creates a new account with the default currency and a generated unique ID @@ -170,7 +151,7 @@ public Account(String name) { this.mFullName = mName; setCommodity(Commodity.DEFAULT_COMMODITY); } - + /** * Overloaded constructor * @param name Name of the account @@ -256,11 +237,11 @@ public void addTransaction(Transaction transaction){ transaction.setCommodity(mCommodity); mTransactionsList.add(transaction); } - + /** * Sets a list of transactions for this account. * Overrides any previous transactions with those in the list. - * The account UID and currency of the transactions will be set to the unique ID + * The account UID and currency of the transactions will be set to the unique ID * and currency of the account respectively * @param transactionsList List of {@link Transaction}s to be set. */ @@ -275,7 +256,7 @@ public void setTransactions(List transactionsList){ public List getTransactions(){ return mTransactionsList; } - + /** * Returns the number of transactions in this account * @return Number transactions in account @@ -319,13 +300,12 @@ public void setColor(int color) { /** * Sets the color of the account. - * @param colorCode Color code to be set in the format #rrggbb or #rgb - * @throws java.lang.IllegalArgumentException if the color code is not properly formatted + * @param colorCode Color code to be set in the format #rrggbb + * @throws java.lang.IllegalArgumentException if the color code is not properly formatted or + * the color is transparent. */ + //TODO: Allow use of #aarrggbb format as well public void setColor(@NonNull String colorCode) { - if (!Pattern.matches(COLOR_HEX_REGEX, colorCode)) - throw new IllegalArgumentException("Invalid color hex code: " + colorCode); - setColor(Color.parseColor(colorCode)); } From 5a9ee0418b7d59778fa9a6b9aa1651c40b9dec54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 4 Apr 2016 18:52:32 +0200 Subject: [PATCH 05/15] Fix the javadoc of some methods refering to Account's fields. --- .../main/java/org/gnucash/android/model/Account.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/model/Account.java b/app/src/main/java/org/gnucash/android/model/Account.java index e89c9d47c..53fa57aab 100644 --- a/app/src/main/java/org/gnucash/android/model/Account.java +++ b/app/src/main/java/org/gnucash/android/model/Account.java @@ -197,16 +197,16 @@ public void setFullName(String fullName) { } /** - * Returns the account mDescription - * @return String with mDescription + * Returns the account description + * @return String with description */ public String getDescription() { return mDescription; } /** - * Sets the account mDescription - * @param description String mDescription + * Sets the account description + * @param description Account description */ public void setDescription(@NonNull String description) { this.mDescription = description; @@ -326,7 +326,7 @@ public void setFavorite(boolean isFavorite) { } /** - * @return the mCurrency + * Returns the currency for this account. */ public Currency getCurrency() { return Currency.getInstance(mCurrencyCode); @@ -342,7 +342,6 @@ public void setCurrencyCode(String currencyCode){ /** * Return the commodity for this account - * @return */ public Commodity getCommodity(){ return mCommodity; From afcac8e5afa5992cd4d041843cf4625188761cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Tue, 5 Apr 2016 22:53:19 +0200 Subject: [PATCH 06/15] Fix code inspector issues. --- .../gnucash/android/db/AccountsDbAdapter.java | 10 +++++----- .../android/ui/account/AccountFormFragment.java | 17 +++++------------ .../android/ui/report/PieChartFragment.java | 2 -- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java index d867ee2e9..f364e37fe 100644 --- a/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/main/java/org/gnucash/android/db/AccountsDbAdapter.java @@ -601,7 +601,7 @@ public String createAccountHierarchy(String fullName, AccountType accountType) { String[] tokens = fullName.trim().split(ACCOUNT_NAME_SEPARATOR); String uid = getOrCreateGnuCashRootAccountUID(); String parentName = ""; - ArrayList accountsList = new ArrayList(); + ArrayList accountsList = new ArrayList<>(); for (String token : tokens) { parentName += token; String parentUID = findAccountUidByFullName(parentName); @@ -841,8 +841,8 @@ public Money getAccountsBalance(@NonNull List accountUIDList, long start public List getDescendantAccountUIDs(String accountUID, String where, String[] whereArgs) { // accountsList will hold accountUID with all descendant accounts. // accountsListLevel will hold descendant accounts of the same level - ArrayList accountsList = new ArrayList(); - ArrayList accountsListLevel = new ArrayList(); + ArrayList accountsList = new ArrayList<>(); + ArrayList accountsListLevel = new ArrayList<>(); accountsListLevel.add(accountUID); for (;;) { Cursor cursor = mDb.query(AccountEntry.TABLE_NAME, @@ -1105,14 +1105,14 @@ public boolean isFavoriteAccount(String accountUID){ */ public List getAllOpeningBalanceTransactions(){ Cursor cursor = fetchAccounts(null, null, null); - List openingTransactions = new ArrayList(); + List openingTransactions = new ArrayList<>(); try { SplitsDbAdapter splitsDbAdapter = mTransactionsAdapter.getSplitDbAdapter(); while (cursor.moveToNext()) { long id = cursor.getLong(cursor.getColumnIndexOrThrow(AccountEntry._ID)); String accountUID = getUID(id); String currencyCode = getCurrencyCode(accountUID); - ArrayList accountList = new ArrayList(); + ArrayList accountList = new ArrayList<>(); accountList.add(accountUID); Money balance = splitsDbAdapter.computeSplitBalance(accountList, currencyCode, getAccountType(accountUID).hasDebitNormalBalance()); diff --git a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java index a29b90816..a6aa11250 100644 --- a/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/account/AccountFormFragment.java @@ -106,12 +106,6 @@ public class AccountFormFragment extends Fragment { */ private AccountsDbAdapter mAccountsDbAdapter; - - /** - * List of all currency codes (ISO 4217) supported by the app - */ - private List mCurrencyCodes; - /** * GUID of the parent account * This value is set to the parent account of the transaction being edited or @@ -400,10 +394,9 @@ private void initializeViewsWithAccount(Account account){ setDefaultTransferAccountSelection(doubleDefaultAccountId, true); } else { String currentAccountUID = account.getParentUID(); - long defaultTransferAccountID = 0; String rootAccountUID = mAccountsDbAdapter.getOrCreateGnuCashRootAccountUID(); while (!currentAccountUID.equals(rootAccountUID)) { - defaultTransferAccountID = mAccountsDbAdapter.getDefaultTransferAccountID(mAccountsDbAdapter.getID(currentAccountUID)); + long defaultTransferAccountID = mAccountsDbAdapter.getDefaultTransferAccountID(mAccountsDbAdapter.getID(currentAccountUID)); if (defaultTransferAccountID > 0) { setDefaultTransferAccountSelection(defaultTransferAccountID, false); break; //we found a parent with default transfer setting @@ -523,7 +516,7 @@ private int[] getAccountColorOptions(){ TypedArray colorTypedArray = res.obtainTypedArray(R.array.account_colors); int[] colorOptions = new int[colorTypedArray.length()]; for (int i = 0; i < colorTypedArray.length(); i++) { - int color = colorTypedArray.getColor(i, R.color.title_green); + int color = colorTypedArray.getColor(i, getResources().getColor(R.color.title_green)); colorOptions[i] = color; } return colorOptions; @@ -678,7 +671,7 @@ private String getAllowedParentAccountTypes(AccountType type) { */ private List getAccountTypeStringList(){ String[] accountTypes = Arrays.toString(AccountType.values()).replaceAll("\\[|]", "").split(","); - List accountTypesList = new ArrayList(); + List accountTypesList = new ArrayList<>(); for (String accountType : accountTypes) { accountTypesList.add(accountType.trim()); } @@ -690,7 +683,7 @@ private List getAccountTypeStringList(){ */ private void loadAccountTypesList(){ String[] accountTypes = getResources().getStringArray(R.array.account_type_entry_values); - ArrayAdapter accountTypesAdapter = new ArrayAdapter( + ArrayAdapter accountTypesAdapter = new ArrayAdapter<>( getActivity(), android.R.layout.simple_list_item_1, accountTypes); accountTypesAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -805,7 +798,7 @@ private void saveAccount() { null )); } - HashMap mapAccount = new HashMap(); + HashMap mapAccount = new HashMap<>(); for (Account acct : accountsToUpdate) mapAccount.put(acct.getUID(), acct); for (String uid: mDescendantAccountUIDs) { // mAccountsDbAdapter.getDescendantAccountUIDs() will ensure a parent-child order diff --git a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java index ac1080cf5..f4e7692a7 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/PieChartFragment.java @@ -85,7 +85,6 @@ public class PieChartFragment extends Fragment implements OnChartValueSelectedLi @Bind(R.id.selected_chart_slice) TextView mSelectedValueTextView; private AccountsDbAdapter mAccountsDbAdapter; - private TransactionsDbAdapter mTransactionsDbAdapter; private AccountType mAccountType; @@ -127,7 +126,6 @@ public void onActivityCreated(@Nullable Bundle savedInstanceState) { .getBoolean(getString(R.string.key_use_account_color), false); mAccountsDbAdapter = AccountsDbAdapter.getInstance(); - mTransactionsDbAdapter = TransactionsDbAdapter.getInstance(); mCurrencyCode = GnuCashApplication.getDefaultCurrencyCode(); From 66cc5332e67e04cb6ce00c558237ea32a77bc627 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Thu, 10 Mar 2016 19:07:02 +0100 Subject: [PATCH 07/15] Avoid losing precision when the user enters an exchange rate. We were storing the rate as originAmount/convertedAmount, which was limited to the precision of the currencies. Now we store directly the entered rate. Fixes https://github.com/codinguser/gnucash-android/issues/479 --- .../java/org/gnucash/android/model/Price.java | 33 ++++++++++++ .../dialog/TransferFundsDialogFragment.java | 45 +++++++++------- .../android/test/unit/model/PriceTest.java | 54 +++++++++++++++++++ 3 files changed, 114 insertions(+), 18 deletions(-) create mode 100644 app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java diff --git a/app/src/main/java/org/gnucash/android/model/Price.java b/app/src/main/java/org/gnucash/android/model/Price.java index 79c572f10..7ecdd1011 100644 --- a/app/src/main/java/org/gnucash/android/model/Price.java +++ b/app/src/main/java/org/gnucash/android/model/Price.java @@ -2,7 +2,11 @@ import org.gnucash.android.util.TimestampHelper; + +import java.math.BigDecimal; import java.sql.Timestamp; +import java.text.DecimalFormat; +import java.text.NumberFormat; /** * Model for commodity prices @@ -37,6 +41,19 @@ public Price(String commodityUID, String currencyUID){ mDate = TimestampHelper.getTimestampFromNow(); } + /** + * Create new instance with the GUIDs of the commodities and the specified exchange rate. + * @param commodity1UID GUID of the origin commodity + * @param commodity2UID GUID of the target commodity + * @param exchangeRate exchange rate between the commodities + */ + public Price(String commodity1UID, String commodity2UID, BigDecimal exchangeRate) { + this(commodity1UID, commodity2UID); + // Store 0.1234 as 1234/10000 + setValueNum(exchangeRate.unscaledValue().longValue()); + setValueDenom(BigDecimal.ONE.scaleByPowerOfTen(exchangeRate.scale()).longValue()); + } + public String getCommodityUID() { return mCommodityUID; } @@ -123,4 +140,20 @@ public void reduce() { mValueDenom /= commonDivisor; } } + + /** + * Returns the exchange rate as a string formatted with the default locale. + * + *

It will have up to 6 decimal places. + * + *

Example: "0.123456" + */ + @Override + public String toString() { + BigDecimal numerator = new BigDecimal(mValueNum); + BigDecimal denominator = new BigDecimal(mValueDenom); + DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); + formatter.setMaximumFractionDigits(6); + return formatter.format(numerator.divide(denominator)); + } } 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 2fccd5461..3ab8291ff 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 @@ -116,17 +116,21 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa Commodity currencyCommodity = commoditiesDbAdapter.getCommodity(mTargetCurrency.getCurrencyCode()); String currencyUID = currencyCommodity.getUID(); PricesDbAdapter pricesDbAdapter = PricesDbAdapter.getInstance(); - Pair price = pricesDbAdapter.getPrice(commodityUID, currencyUID); + Pair pricePair = pricesDbAdapter.getPrice(commodityUID, currencyUID); - if (price.first > 0 && price.second > 0) { + if (pricePair.first > 0 && pricePair.second > 0) { // a valid price exists - BigDecimal numerator = new BigDecimal(price.first); - BigDecimal denominator = new BigDecimal(price.second); - DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); - mExchangeRateInput.setText(formatter.format(numerator.divide(denominator, MathContext.DECIMAL32))); + Price price = new Price(commodityUID, currencyUID); + price.setValueNum(pricePair.first); + price.setValueDenom(pricePair.second); + mExchangeRateInput.setText(price.toString()); + + BigDecimal numerator = new BigDecimal(pricePair.first); + BigDecimal denominator = new BigDecimal(pricePair.second); // convertedAmount = mOriginAmount * numerator / denominator BigDecimal convertedAmount = mOriginAmount.asBigDecimal().multiply(numerator) .divide(denominator, currencyCommodity.getSmallestFractionDigits(), BigDecimal.ROUND_HALF_EVEN); + DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); mConvertedAmountInput.setText(formatter.format(convertedAmount)); } @@ -194,17 +198,24 @@ public Dialog onCreateDialog(Bundle savedInstanceState) { * Converts the currency amount with the given exchange rate and saves the price to the db */ private void transferFunds() { + Price price = null; + + CommoditiesDbAdapter commoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); + String originCommodityUID = commoditiesDbAdapter.getCommodityUID(mOriginAmount.getCurrency().getCurrencyCode()); + String targetCommodityUID = commoditiesDbAdapter.getCommodityUID(mTargetCurrency.getCurrencyCode()); + if (mExchangeRateRadioButton.isChecked()){ + BigDecimal rate; String exchangeRateString = mExchangeRateInput.getText().toString(); DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); formatter.setParseBigDecimal(true); - BigDecimal rate; try { rate = (BigDecimal) formatter.parse(exchangeRateString); } catch (ParseException e) { mExchangeRateInputLayout.setError(getString(R.string.error_invalid_exchange_rate)); return; } + price = new Price(originCommodityUID, targetCommodityUID, rate); mConvertedAmount = mOriginAmount.multiply(rate); } @@ -217,22 +228,20 @@ private void transferFunds() { BigDecimal amount = TransactionFormFragment.parseInputToDecimal(convertedAmount); mConvertedAmount = new Money(amount, Commodity.getInstance(mTargetCurrency.getCurrencyCode())); - } - if (mOnTransferFundsListener != null) { - PricesDbAdapter pricesDbAdapter = PricesDbAdapter.getInstance(); - CommoditiesDbAdapter commoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); - Price price = new Price(commoditiesDbAdapter.getCommodityUID(mOriginAmount.getCurrency().getCurrencyCode()), - commoditiesDbAdapter.getCommodityUID(mTargetCurrency.getCurrencyCode())); - price.setSource(Price.SOURCE_USER); - // fractions cannot be exacted represented by BigDecimal. + price = new Price(originCommodityUID, targetCommodityUID); + // fractions cannot be exactly represented by BigDecimal. price.setValueNum(mConvertedAmount.getNumerator() * mOriginAmount.getDenominator()); price.setValueDenom(mOriginAmount.getNumerator() * mConvertedAmount.getDenominator()); - price.reduce(); - pricesDbAdapter.addRecord(price); + } + price.setSource(Price.SOURCE_USER); + price.reduce(); + PricesDbAdapter.getInstance().addRecord(price); + + if (mOnTransferFundsListener != null) mOnTransferFundsListener.transferComplete(mConvertedAmount); - } + dismiss(); } diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java new file mode 100644 index 000000000..8df91036c --- /dev/null +++ b/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java @@ -0,0 +1,54 @@ +/* + * 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.model; + +import org.gnucash.android.model.Price; +import org.junit.Test; + +import java.math.BigDecimal; +import java.util.Locale; + +import static org.assertj.core.api.Assertions.assertThat; + + +public class PriceTest { + @Test + public void creatingFromExchangeRate_ShouldGetPrecisionRight() { + Locale.setDefault(Locale.US); + + String exchangeRateString = "0.123456"; + BigDecimal exchangeRate = new BigDecimal(exchangeRateString); + Price price = new Price("commodity1UID", "commodity2UID", exchangeRate); + assertThat(price.toString()).isEqualTo(exchangeRateString); + + // ensure we don't get more decimal places than needed (0.123000) + exchangeRateString = "0.123"; + exchangeRate = new BigDecimal(exchangeRateString); + price = new Price("commodity1UID", "commodity2UID", exchangeRate); + assertThat(price.toString()).isEqualTo(exchangeRateString); + } + + @Test + public void toString_shouldUseDefaultLocale() { + Locale.setDefault(Locale.GERMANY); + + String exchangeRateString = "1.234"; + BigDecimal exchangeRate = new BigDecimal(exchangeRateString); + Price price = new Price("commodity1UID", "commodity2UID", exchangeRate); + assertThat(price.toString()).isEqualTo("1,234"); + } +} From 876bf34fac4930548100e374835802b67d9c0790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 21 Mar 2016 20:15:53 +0100 Subject: [PATCH 08/15] Avoid test in AccountsDbAdapterTest depending on the default locale. importingXml_shouldSetDefaultCurrency() broke after setting the default locale in Price.toString_shouldUseDefaultLocale() in the previous commit. --- .../android/test/unit/db/AccountsDbAdapterTest.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) 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 06a8d021e..c9fdb0f6e 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 @@ -413,6 +413,9 @@ public void shouldSetDefaultTransferColumnToNull_WhenTheAccountIsDeleted(){ */ @Test public void importingXml_shouldSetDefaultCurrency(){ + String expectedCode = GnuCashApplication.getDefaultCurrencyCode(); + Commodity expectedDefaultCommodity = CommoditiesDbAdapter.getInstance().getCommodity(expectedCode); + GnuCashApplication.setDefaultCurrencyCode("JPY"); assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo("JPY"); @@ -422,11 +425,6 @@ public void importingXml_shouldSetDefaultCurrency(){ loadDefaultAccounts(); assertThat(GnuCashApplication.getDefaultCurrencyCode()).isNotEqualTo("JPY"); - - Currency currency = Currency.getInstance(GnuCashApplication.getDefaultLocale()); - String expectedCode = currency.getCurrencyCode(); - Commodity expectedDefaultCommodity = CommoditiesDbAdapter.getInstance().getCommodity(expectedCode); - assertThat(GnuCashApplication.getDefaultCurrencyCode()).isEqualTo(expectedCode); assertThat(Commodity.DEFAULT_COMMODITY).isEqualTo(expectedDefaultCommodity); From 45fafb5870b0919a895c24104cc544c97f93c423 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 21 Mar 2016 19:18:37 +0100 Subject: [PATCH 09/15] Automatically reduce fraction in Price when getting its elements. --- .../java/org/gnucash/android/model/Price.java | 4 +++- .../dialog/TransferFundsDialogFragment.java | 1 - .../android/test/unit/model/PriceTest.java | 22 +++++++++++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/model/Price.java b/app/src/main/java/org/gnucash/android/model/Price.java index 7ecdd1011..df02d380a 100644 --- a/app/src/main/java/org/gnucash/android/model/Price.java +++ b/app/src/main/java/org/gnucash/android/model/Price.java @@ -95,6 +95,7 @@ public void setType(String type) { } public long getValueNum() { + reduce(); return mValueNum; } @@ -103,6 +104,7 @@ public void setValueNum(long valueNum) { } public long getValueDenom() { + reduce(); return mValueDenom; } @@ -110,7 +112,7 @@ public void setValueDenom(long valueDenom) { this.mValueDenom = valueDenom; } - public void reduce() { + private void reduce() { if (mValueDenom < 0) { mValueDenom = -mValueDenom; mValueNum = -mValueNum; 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 3ab8291ff..73dcc89b4 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 @@ -236,7 +236,6 @@ private void transferFunds() { } price.setSource(Price.SOURCE_USER); - price.reduce(); PricesDbAdapter.getInstance().addRecord(price); if (mOnTransferFundsListener != null) diff --git a/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java b/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java index 8df91036c..b9abc63e2 100644 --- a/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java +++ b/app/src/test/java/org/gnucash/android/test/unit/model/PriceTest.java @@ -51,4 +51,26 @@ public void toString_shouldUseDefaultLocale() { Price price = new Price("commodity1UID", "commodity2UID", exchangeRate); assertThat(price.toString()).isEqualTo("1,234"); } + + @Test + public void getNumerator_shouldReduceAutomatically() { + long numerator = 1; + long denominator = 3; + Price price = new Price(); + + price.setValueNum(numerator * 2); + price.setValueDenom(denominator * 2); + assertThat(price.getValueNum()).isEqualTo(numerator); + } + + @Test + public void getDenominator_shouldReduceAutomatically() { + long numerator = 1; + long denominator = 3; + Price price = new Price(); + + price.setValueNum(numerator * 2); + price.setValueDenom(denominator * 2); + assertThat(price.getValueDenom()).isEqualTo(denominator); + } } From e8e6ed393e70de93ef8a764dec23d50194f0d169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 21 Mar 2016 13:02:19 +0100 Subject: [PATCH 10/15] Set the correct currency for the converted amount when derived from the exchange rate. --- .../ui/transaction/dialog/TransferFundsDialogFragment.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) 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 73dcc89b4..11c271d89 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 @@ -216,7 +216,9 @@ private void transferFunds() { return; } price = new Price(originCommodityUID, targetCommodityUID, rate); - mConvertedAmount = mOriginAmount.multiply(rate); + + Commodity targetCommodity = Commodity.getInstance(mTargetCurrency.getCurrencyCode()); + mConvertedAmount = mOriginAmount.multiply(rate).withCurrency(targetCommodity); } if (mConvertedAmountRadioButton.isChecked()){ From 07756f31487c30921499273984b2ff5ea9dea9e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Mon, 21 Mar 2016 13:06:31 +0100 Subject: [PATCH 11/15] Simplify the use of some variables. In both cases all uses called .getCurrencyCode(). --- .../dialog/TransferFundsDialogFragment.java | 27 +++++++++---------- 1 file changed, 13 insertions(+), 14 deletions(-) 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 11c271d89..b74efd8f0 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 @@ -46,7 +46,6 @@ import org.gnucash.android.ui.util.OnTransferFundsListener; import java.math.BigDecimal; -import java.math.MathContext; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; @@ -80,7 +79,7 @@ public class TransferFundsDialogFragment extends DialogFragment { @Bind(R.id.btn_save) Button mSaveButton; @Bind(R.id.btn_cancel) Button mCancelButton; Money mOriginAmount; - Currency mTargetCurrency; + String mTargetCurrencyCode; Money mConvertedAmount; OnTransferFundsListener mOnTransferFundsListener; @@ -89,7 +88,7 @@ public static TransferFundsDialogFragment getInstance(Money transactionAmount, S OnTransferFundsListener transferFundsListener){ TransferFundsDialogFragment fragment = new TransferFundsDialogFragment(); fragment.mOriginAmount = transactionAmount; - fragment.mTargetCurrency = Currency.getInstance(targetCurrencyCode); + fragment.mTargetCurrencyCode = Currency.getInstance(targetCurrencyCode).getCurrencyCode(); fragment.mOnTransferFundsListener = transferFundsListener; return fragment; } @@ -101,19 +100,19 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa ButterKnife.bind(this, view); TransactionsActivity.displayBalance(mStartAmountLabel, mOriginAmount); - Currency fromCurrency = mOriginAmount.getCurrency(); - mFromCurrencyLabel.setText(fromCurrency.getCurrencyCode()); - mToCurrencyLabel.setText(mTargetCurrency.getCurrencyCode()); - mConvertedAmountCurrencyLabel.setText(mTargetCurrency.getCurrencyCode()); + String fromCurrencyCode = mOriginAmount.getCurrency().getCurrencyCode(); + mFromCurrencyLabel.setText(fromCurrencyCode); + mToCurrencyLabel.setText(mTargetCurrencyCode); + mConvertedAmountCurrencyLabel.setText(mTargetCurrencyCode); mSampleExchangeRate.setText(String.format(getString(R.string.sample_exchange_rate), - fromCurrency.getCurrencyCode(), - mTargetCurrency.getCurrencyCode())); + fromCurrencyCode, + mTargetCurrencyCode)); final InputLayoutErrorClearer textChangeListener = new InputLayoutErrorClearer(); CommoditiesDbAdapter commoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); - String commodityUID = commoditiesDbAdapter.getCommodityUID(fromCurrency.getCurrencyCode()); - Commodity currencyCommodity = commoditiesDbAdapter.getCommodity(mTargetCurrency.getCurrencyCode()); + String commodityUID = commoditiesDbAdapter.getCommodityUID(fromCurrencyCode); + Commodity currencyCommodity = commoditiesDbAdapter.getCommodity(mTargetCurrencyCode); String currencyUID = currencyCommodity.getUID(); PricesDbAdapter pricesDbAdapter = PricesDbAdapter.getInstance(); Pair pricePair = pricesDbAdapter.getPrice(commodityUID, currencyUID); @@ -202,7 +201,7 @@ private void transferFunds() { CommoditiesDbAdapter commoditiesDbAdapter = CommoditiesDbAdapter.getInstance(); String originCommodityUID = commoditiesDbAdapter.getCommodityUID(mOriginAmount.getCurrency().getCurrencyCode()); - String targetCommodityUID = commoditiesDbAdapter.getCommodityUID(mTargetCurrency.getCurrencyCode()); + String targetCommodityUID = commoditiesDbAdapter.getCommodityUID(mTargetCurrencyCode); if (mExchangeRateRadioButton.isChecked()){ BigDecimal rate; @@ -217,7 +216,7 @@ private void transferFunds() { } price = new Price(originCommodityUID, targetCommodityUID, rate); - Commodity targetCommodity = Commodity.getInstance(mTargetCurrency.getCurrencyCode()); + Commodity targetCommodity = Commodity.getInstance(mTargetCurrencyCode); mConvertedAmount = mOriginAmount.multiply(rate).withCurrency(targetCommodity); } @@ -229,7 +228,7 @@ private void transferFunds() { } BigDecimal amount = TransactionFormFragment.parseInputToDecimal(convertedAmount); - mConvertedAmount = new Money(amount, Commodity.getInstance(mTargetCurrency.getCurrencyCode())); + mConvertedAmount = new Money(amount, Commodity.getInstance(mTargetCurrencyCode)); price = new Price(originCommodityUID, targetCommodityUID); // fractions cannot be exactly represented by BigDecimal. From cbfb3cc63c366fbe2c293334e7ebc0fcc9526afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Tue, 22 Mar 2016 11:35:33 +0100 Subject: [PATCH 12/15] Remove last use of deprecated AmountInputFormatter. --- .../dialog/TransferFundsDialogFragment.java | 2 - .../android/ui/util/AmountInputFormatter.java | 92 ------------------- .../main/res/layout/dialog_transfer_funds.xml | 3 + 3 files changed, 3 insertions(+), 94 deletions(-) delete mode 100644 app/src/main/java/org/gnucash/android/ui/util/AmountInputFormatter.java 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 b74efd8f0..9f2bd1be9 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 @@ -42,7 +42,6 @@ import org.gnucash.android.model.Price; import org.gnucash.android.ui.transaction.TransactionFormFragment; import org.gnucash.android.ui.transaction.TransactionsActivity; -import org.gnucash.android.ui.util.AmountInputFormatter; import org.gnucash.android.ui.util.OnTransferFundsListener; import java.math.BigDecimal; @@ -135,7 +134,6 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa mExchangeRateInput.addTextChangedListener(textChangeListener); mConvertedAmountInput.addTextChangedListener(textChangeListener); - mConvertedAmountInput.addTextChangedListener(new AmountInputFormatter(mConvertedAmountInput)); mConvertedAmountRadioButton.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override diff --git a/app/src/main/java/org/gnucash/android/ui/util/AmountInputFormatter.java b/app/src/main/java/org/gnucash/android/ui/util/AmountInputFormatter.java deleted file mode 100644 index 1e9af5c2c..000000000 --- a/app/src/main/java/org/gnucash/android/ui/util/AmountInputFormatter.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2014 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.ui.util; - -import android.text.Editable; -import android.text.TextWatcher; -import android.widget.EditText; - -import org.gnucash.android.ui.transaction.TransactionFormFragment; - -import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.Locale; - -/** - * Captures input string in the amount input field and parses it into a formatted amount - * The amount input field allows numbers to be input sequentially and they are parsed - * into a string with 2 decimal places. This means inputting 245 will result in the amount - * of 2.45 - * - * @author Ngewi Fet - * @deprecated Use {@link org.gnucash.android.ui.util.widget.CalculatorEditText} for getting input amounts from the user - */ -@Deprecated -public class AmountInputFormatter implements TextWatcher { - private String current = "0"; - private EditText amountEditText; - /** - * Flag to note if the user has manually edited the amount of the transaction - */ - private boolean isModified = false; - - public AmountInputFormatter(EditText amountInput) { - this.amountEditText = amountInput; - } - - @Override - public void afterTextChanged(Editable s) { - if (s.length() == 0 || s.toString().equals(current)) - return; -//make sure that the sign of the input is in line with the type button state - BigDecimal amount = TransactionFormFragment.parseInputToDecimal(s.toString()); - - DecimalFormat formatter = (DecimalFormat) NumberFormat.getInstance(Locale.getDefault()); - formatter.setMinimumFractionDigits(2); //TODO: Use fraction of the currency in question - formatter.setMaximumFractionDigits(2); - - current = formatter.format(amount.doubleValue()); //TODO: Try with Bigdecimal string instead of double - amountEditText.removeTextChangedListener(this); - amountEditText.setText(current); - amountEditText.setSelection(current.length()); - amountEditText.addTextChangedListener(this); - - isModified = true; - } - - @Override - public void beforeTextChanged(CharSequence s, int start, int count, - int after) { - // nothing to see here, move along - } - - @Override - public void onTextChanged(CharSequence s, int start, int before, - int count) { - // nothing to see here, move along - isModified = true; - } - - /** - * Returns true if input has been entered into the view - * - * @return true if the view has been modified, false otherwise. - */ - public boolean isInputModified() { - return isModified; - } -} diff --git a/app/src/main/res/layout/dialog_transfer_funds.xml b/app/src/main/res/layout/dialog_transfer_funds.xml index b5cd006ae..d0a3093f5 100644 --- a/app/src/main/res/layout/dialog_transfer_funds.xml +++ b/app/src/main/res/layout/dialog_transfer_funds.xml @@ -138,10 +138,13 @@ android:layout_width="0dp" android:layout_weight="2" android:layout_height="wrap_content"> + From 772e15f6785a31d31c8e6b6b627b31dfb8e2bc69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=80lex=20Magaz=20Gra=C3=A7a?= Date: Tue, 22 Mar 2016 13:06:42 +0100 Subject: [PATCH 13/15] Unify parsing of amounts. --- .../transaction/TransactionFormFragment.java | 17 ---------- .../dialog/TransferFundsDialogFragment.java | 34 ++++++++++++------- app/src/main/res/values/strings.xml | 1 + 3 files changed, 23 insertions(+), 29 deletions(-) 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 f5ce13d0a..2735a38d5 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 @@ -1013,23 +1013,6 @@ public static String stripCurrencyFormatting(String s){ return stripped; } - /** - * Parse an input string into a {@link BigDecimal} - * This method expects the amount including the decimal part - * @param amountString String with amount information - * @return BigDecimal with the amount parsed from amountString - */ - public static BigDecimal parseInputToDecimal(String amountString){ - String clean = stripCurrencyFormatting(amountString); - if (clean.length() == 0) //empty string - return BigDecimal.ZERO; - //all amounts are input to 2 decimal places, so after removing decimal separator, divide by 100 - //TODO: Handle currencies with different kinds of decimal places - return new BigDecimal(clean).setScale(2, - RoundingMode.HALF_EVEN).divide(new BigDecimal(100), 2, - RoundingMode.HALF_EVEN); - } - @Override public void transferComplete(Money amount) { mSplitQuantity = amount; 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 9f2bd1be9..4a48753fd 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 @@ -40,7 +40,6 @@ import org.gnucash.android.model.Commodity; import org.gnucash.android.model.Money; import org.gnucash.android.model.Price; -import org.gnucash.android.ui.transaction.TransactionFormFragment; import org.gnucash.android.ui.transaction.TransactionsActivity; import org.gnucash.android.ui.util.OnTransferFundsListener; @@ -48,6 +47,7 @@ import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.ParseException; +import java.text.ParsePosition; import java.util.Currency; import butterknife.Bind; @@ -201,13 +201,10 @@ private void transferFunds() { String originCommodityUID = commoditiesDbAdapter.getCommodityUID(mOriginAmount.getCurrency().getCurrencyCode()); String targetCommodityUID = commoditiesDbAdapter.getCommodityUID(mTargetCurrencyCode); - if (mExchangeRateRadioButton.isChecked()){ + if (mExchangeRateRadioButton.isChecked()) { BigDecimal rate; - String exchangeRateString = mExchangeRateInput.getText().toString(); - DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); - formatter.setParseBigDecimal(true); try { - rate = (BigDecimal) formatter.parse(exchangeRateString); + rate = parseAmount(mExchangeRateInput.getText().toString()); } catch (ParseException e) { mExchangeRateInputLayout.setError(getString(R.string.error_invalid_exchange_rate)); return; @@ -218,14 +215,14 @@ private void transferFunds() { mConvertedAmount = mOriginAmount.multiply(rate).withCurrency(targetCommodity); } - if (mConvertedAmountRadioButton.isChecked()){ - String convertedAmount = mConvertedAmountInput.getText().toString(); - if (convertedAmount.isEmpty()){ - mConvertedAmountInputLayout.setError(getString(R.string.error_converted_amount_required)); + if (mConvertedAmountRadioButton.isChecked()) { + BigDecimal amount; + try { + amount = parseAmount(mConvertedAmountInput.getText().toString()); + } catch (ParseException e) { + mConvertedAmountInputLayout.setError(getString(R.string.error_invalid_amount)); return; } - - BigDecimal amount = TransactionFormFragment.parseInputToDecimal(convertedAmount); mConvertedAmount = new Money(amount, Commodity.getInstance(mTargetCurrencyCode)); price = new Price(originCommodityUID, targetCommodityUID); @@ -243,6 +240,19 @@ private void transferFunds() { dismiss(); } + private BigDecimal parseAmount(String amount) throws ParseException { + DecimalFormat formatter = (DecimalFormat) NumberFormat.getNumberInstance(); + formatter.setParseBigDecimal(true); + ParsePosition parsePosition = new ParsePosition(0); + BigDecimal parsedAmount = (BigDecimal) formatter.parse(amount, parsePosition); + + // Ensure any mistyping by the user is caught instead of partially parsed + if (parsePosition.getIndex() < amount.length()) + throw new ParseException("Parse error", parsePosition.getErrorIndex()); + + return parsedAmount; + } + /** * Hides the error message from mConvertedAmountInputLayout and mExchangeRateInputLayout * when the user edits their content. diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 835d47488..d3ac600e3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -393,6 +393,7 @@ Duplicate Invalid exchange rate e.g. 1 %1$s = x.xx %2$s + Invalid amount Current month Last 3 months From bee63a9e489a8d2a01408a128649621b86ea9316 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Tue, 19 Apr 2016 10:06:25 +0200 Subject: [PATCH 14/15] Update translations --- app/src/main/res/values-af-rZA/strings.xml | 4 ++ app/src/main/res/values-ar-rSA/strings.xml | 4 ++ app/src/main/res/values-ca-rES/strings.xml | 12 ++-- app/src/main/res/values-cs-rCZ/strings.xml | 4 ++ app/src/main/res/values-el-rGR/strings.xml | 4 ++ app/src/main/res/values-en-rGB/strings.xml | 4 ++ app/src/main/res/values-es/strings.xml | 6 +- app/src/main/res/values-fi-rFI/strings.xml | 4 ++ app/src/main/res/values-fr/strings.xml | 14 ++-- app/src/main/res/values-it-rIT/strings.xml | 12 ++-- app/src/main/res/values-iw-rIL/strings.xml | 4 ++ app/src/main/res/values-ja-rJP/strings.xml | 26 ++++---- app/src/main/res/values-ko-rKR/strings.xml | 4 ++ app/src/main/res/values-pl-rPL/strings.xml | 74 +++++++++++----------- app/src/main/res/values-pt-rPT/strings.xml | 2 - app/src/main/res/values-ro-rRO/strings.xml | 2 - app/src/main/res/values-ru/strings.xml | 2 - app/src/main/res/values-sv-rSE/strings.xml | 6 +- app/src/main/res/values-vi-rVN/strings.xml | 4 ++ app/src/main/res/values-zh-rCN/strings.xml | 10 ++- app/src/main/res/values/strings.xml | 2 +- 21 files changed, 130 insertions(+), 74 deletions(-) diff --git a/app/src/main/res/values-af-rZA/strings.xml b/app/src/main/res/values-af-rZA/strings.xml index fdb319544..bd0307252 100644 --- a/app/src/main/res/values-af-rZA/strings.xml +++ b/app/src/main/res/values-af-rZA/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -199,7 +200,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-ar-rSA/strings.xml b/app/src/main/res/values-ar-rSA/strings.xml index 8411d707b..c61e1bf70 100644 --- a/app/src/main/res/values-ar-rSA/strings.xml +++ b/app/src/main/res/values-ar-rSA/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -203,7 +204,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-ca-rES/strings.xml b/app/src/main/res/values-ca-rES/strings.xml index 731fe140e..699c7bceb 100644 --- a/app/src/main/res/values-ca-rES/strings.xml +++ b/app/src/main/res/values-ca-rES/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Exporta els assentaments… Periodicitat + Desequilibri Exporting transactions No recurring transactions to display. @@ -186,12 +187,12 @@ PASSIU INGRESSOS DESPESES - PAYABLE - RECEIVABLE + PAGAMENTS PENDENTS + INGRESSOS PENDENTS EQUITY MONEDA STOCK - MUTUAL FUND + FONS D\'INVERSIÓ TRADING @@ -199,7 +200,10 @@ OFX XML + Seleccioneu un color + + Color del compte i tipus Suprimeix els subcomptes Recents @@ -219,7 +223,7 @@ Spend Receive Withdrawal - Deposit + Ingrés Pagament Charge Decrease diff --git a/app/src/main/res/values-cs-rCZ/strings.xml b/app/src/main/res/values-cs-rCZ/strings.xml index 3924a847f..e46859e63 100644 --- a/app/src/main/res/values-cs-rCZ/strings.xml +++ b/app/src/main/res/values-cs-rCZ/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -200,7 +201,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-el-rGR/strings.xml b/app/src/main/res/values-el-rGR/strings.xml index b8ff313dd..2ccce0e2d 100644 --- a/app/src/main/res/values-el-rGR/strings.xml +++ b/app/src/main/res/values-el-rGR/strings.xml @@ -177,6 +177,7 @@ Μορφή αρχείου για προεπιλεγμένη χρήση κατά την εξαγωγή κινήσεων. Εξαγωγή κινήσεων… Επαναλαμβανόμενη + Imbalance Εξαγωγή κινήσεων Δεν υπάρχουν επαναλαμβανόμενες κινήσεις για εμφάνιση. @@ -208,7 +209,10 @@ OFX XML + Επιλογή χρώματος + + Χρώμα Λογαριασμού & Τύπος Διαγραφή υπο-λογαριασμών Πρόσφατοι diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index 973a9b897..7a9948dc7 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -199,7 +200,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index c1fb0f00d..5f05e6e5c 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -166,6 +166,7 @@ Formato de archivo para usar por defecto al exportar transacciones Exportar transacciones… Recurrencia + Descuadre Exportando transacciones No hay transacciones recurrentes que mostrar. @@ -197,7 +198,10 @@ OFX XML + Seleccionar un color + + Color y tipo de cuenta Borrar sub-cuentas Reciente @@ -321,7 +325,7 @@ Este proceso solo recoge información que no permite identificar al usuarioCrear programación de exportación Exportado a: %1$s La leyenda es demasiado larga - Descriptión de la cuenta + Descripción de la cuenta No hay cuentas recientes No hay cuentas favoritas Acciones Programadas diff --git a/app/src/main/res/values-fi-rFI/strings.xml b/app/src/main/res/values-fi-rFI/strings.xml index fdb319544..bd0307252 100644 --- a/app/src/main/res/values-fi-rFI/strings.xml +++ b/app/src/main/res/values-fi-rFI/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -199,7 +200,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index 4ef1360c3..27d6b77e4 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -139,10 +139,10 @@ Passer Entrez un montant pour sauvegarder la transaction - Les transactions multi-devises ne peuvent pas être modifiés + Les transactions multi-devises ne peuvent pas être modifiées Importer des comptes GnuCash Import de comptes - Une érreur s\'est produite pendant l\'import de vos comptes GnuCash + 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 @@ -164,6 +164,7 @@ Format de fichier à utiliser par défaut pour l\'export des transactions Exporter les transactions… Récurrence + Déséquilibre Exportation des transactions Pas de transactions planifiées à afficher. @@ -195,7 +196,10 @@ OFX XML + Sélectionnez une couleur + + Couleur de compte & Type Supprimer les sous-comptes Récent @@ -241,14 +245,14 @@ Favori Panneau de navigation ouvert Panneau de navigation fermé - Raport + Rapports Diagramme Circulaire Graphique linéaire Histogramme - Préférences Raport + Préférences Rapport Sélectionnez la monnaie Couleur du compte dans les rapports - utiliser la couleur du compte dans le diagramme bandes/circulaire + Utiliser la couleur du compte dans le diagramme bandes/circulaire Rapports Tri par taille Show legend diff --git a/app/src/main/res/values-it-rIT/strings.xml b/app/src/main/res/values-it-rIT/strings.xml index 5c6f3d074..9ed6e02c3 100644 --- a/app/src/main/res/values-it-rIT/strings.xml +++ b/app/src/main/res/values-it-rIT/strings.xml @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. --> - + Crea conto Modifica conto Informazioni @@ -165,6 +165,7 @@ Formato di file predefinito da utilizzare per l\'esportazione delle transazioni Esporta transazioni… Ripetizione + Sbilancio Esportazione transazioni in corso Nessuna transazione ricorrente da visualizzare. @@ -196,7 +197,10 @@ OFX XML + Seleziona un colore + + Tipo e colore del conto Elimina i sottoconti Recenti @@ -272,7 +276,7 @@ Tocca per creare una pianificazione Ripristina backup… Backup e esportazione - Sincronizzazione con Dropbox + Sincronizzazione Dropbox Backup Abilita la sincronizzazione con Dropbox Seleziona un file XML di GnuCash @@ -283,7 +287,7 @@ Backup riuscito Backup non riuscito Esporta tutti i conti e tutte le transazioni - Sincronizzazione con Google Drive + Sincronizzazione Google Drive Abilita la sincronizzazione con Google Drive Installa un file manager per selezionare i file Seleziona il backup da ripristinare @@ -382,8 +386,6 @@ Nessuna app compatibile con la ricezione delle transazioni esportate! Sposta... Duplica - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s Mese corrente Ultimi 3 mesi diff --git a/app/src/main/res/values-iw-rIL/strings.xml b/app/src/main/res/values-iw-rIL/strings.xml index fdb319544..bd0307252 100644 --- a/app/src/main/res/values-iw-rIL/strings.xml +++ b/app/src/main/res/values-iw-rIL/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -199,7 +200,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-ja-rJP/strings.xml b/app/src/main/res/values-ja-rJP/strings.xml index 44f56fe5a..6371bea07 100644 --- a/app/src/main/res/values-ja-rJP/strings.xml +++ b/app/src/main/res/values-ja-rJP/strings.xml @@ -163,6 +163,7 @@ 取引のエクスポート時に既定とするファイル形式 取引をエクスポートする... 繰り返し + Imbalance 取引のエクスポート 表示する繰り返し取引がありません @@ -193,7 +194,10 @@ OFX XML + 色を選択 + + 勘定科目の色と種類 補助科目を削除する 履歴 @@ -212,13 +216,13 @@ Memo Spend Receive - Withdrawal - Deposit - Payment - Charge + 出金 + 入金 + 支払い + 請求 Decrease Increase - Income + 収入 Rebate Expense Bill @@ -237,15 +241,15 @@ Transaction splits Imbalance: Add split - Favorite + お気に入り Navigation drawer opened Navigation drawer closed - Reports - Pie Chart - Line Chart - Bar Chart + レポート + 円グラフ + 線グラフ + 棒グラフ Report Preferences - Select currency + 通貨を選択 Account color in reports Use account color in the bar/pie chart Reports diff --git a/app/src/main/res/values-ko-rKR/strings.xml b/app/src/main/res/values-ko-rKR/strings.xml index 47619e9c8..c57a26868 100644 --- a/app/src/main/res/values-ko-rKR/strings.xml +++ b/app/src/main/res/values-ko-rKR/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -198,7 +199,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-pl-rPL/strings.xml b/app/src/main/res/values-pl-rPL/strings.xml index cb0d7af92..bc98d71d6 100644 --- a/app/src/main/res/values-pl-rPL/strings.xml +++ b/app/src/main/res/values-pl-rPL/strings.xml @@ -51,26 +51,27 @@ PRZENIEŚ %1$d wybranych Saldo: - Export To: + Wyeksportuj do: Eksport transakcji Eksportuj wszystkie transakcje - By default, only new transactions since last export will be exported. Check this option to export all transactions + Domyślnie tylko nowe transakcje od ostatniego eksportu, zostaną wyeksportowane. Zaznacz tą opcję, aby eksportować wszystkie transakcje Błąd eksportowania pliku %1$s Eksportuj - Delete transactions after export + Usuń transakcje po eksporcie Wszystkie eksportowane transakcje będą usunięte po zakończeniu eksportu Ustawienia Karta SD DropBox - Google Drive + Dysk Google Udostępnij plik… Przenieś Przenieś %1$d transakcji Konto docelowe Dostęp do Karty SD - Cannot move transactions.\nThe destination account uses a different currency from origin account + Nie można przenieść transakcji. +Konto docelowe używa innej waluty niż konto wyjściowe Ogólne O… Wybierz domyślna walutę @@ -98,11 +99,11 @@ Hasło wyłączone Zmień hasło O GnuCash - A mobile finance management and expense-tracker designed for Android + Mobilny menadżer finansów i agent wydatków stworzony dla Androida O… %1$s plik wyeksportowany do:\n GnuCash Android %1$s eksport - GnuCash Android Export from + GnuCash Android eksport z Transakcje Ustawienia transakcji Ustawienia konta @@ -130,13 +131,12 @@ Włącz tę opcję gdy eksportujesz do aplikacji innej ni GnuCash dla desktopa Co nowego - - New Material app design \n - - Multi-currency transactions\n - - Calculator to transaction amounts\n - - Better reporting options\n - - New help & feedback section\n - - Multiple bug fixes and improvements\n - +- Nowy design aplikacji Material +- Transakcje wielo-walutowe +- Kalkulator kwot transakcji +- Ulepszone opcje raportowania +- Nowe centrum pomocy i feedbacku +- Wiele naprawionych błędów oraz ulepszeń Spocznij Wprowadź kwotę by zapisać transakcję Wielowalutowe transakcje nie mogą być modyfikowane @@ -164,6 +164,7 @@ Format pliku użyty w trakcie eksportowania transakcji Eksport transakcji… Powtarzająca się + Niezbilansowane Eksport transakcji Brak powtarzających się transakcji do wyświetlenia. @@ -189,14 +190,17 @@ WALUTA AKCJE FUNDUSZ WZAJEMNY - TRADING + Handlowy QIF OFX XML + Wybierz kolor + + Kolor i typ konta Usuń sub-konta Ostatnie @@ -234,7 +238,7 @@ OFX nie wspiera transakcji double-entry Generuje osobne pliki QIF dla każdej waluty Podział transakcji - Imbalance: + Niezbilansowanie: Dodaj podział Ulubione Szuflada nawigacyjna otwarta @@ -249,10 +253,10 @@ Użyj koloru konta w wykresie kołowym/słupkowym Raporty Sortuj po rozmarze - Show legend - Show labels - Show percentage - Show average lines + Pokaż legendę + Pokaż etykiety + Pokaż procenty + Pokaż linie średnich Grupuj mniejsze wycinki Brak danych dla wykresu Ogólny @@ -268,7 +272,7 @@ Stuknij aby zaplanować Przywróc kopię zapasową… Kopia zapasowa i eksport - DropBox Sync + Synchronizacja z DropBox Kopia zapasowa Zaznaczy by synchronizowac z DropBox Wybierz plik GnuCash XML @@ -279,7 +283,7 @@ Kopia zapasowa utworzona pomyślnie Błąd tworzenia kopii zapasowej Wyeksportowano wszystkie konta i transakcje - Google Drive Sync + Synchronizacja z Dyskiem Google Wybierz aby synchronizować z Google Drive Zainstaluj managera plików aby wybrać pliki Wybierz kopię zapaswą aby ją przywrócić @@ -292,22 +296,22 @@ Codziennie Co %d dni - Every %d days + Każde %d dni Co tydzień - Co %d tygodnie - Every %d weeks + Co %d tygodni + Co %d tygodni Co miesiąc Co %d miesiące - Every %d months + Co %d miesięcy Co rok Co %d lata - Every %d years + Co %d lat Włącz logowanie błędów Włącz by wysyłać inforamcje o błędach do twórców w celu poleszania aplikacji (zalecane). @@ -376,15 +380,13 @@ Roku Bilans Suma: - 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 - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s + Społeczność Google+ + Tłumacz GnuCash + Udostępnij pomysły, dyskutuj zmiany, lub zgłoś problem + Tłumacz lub sprawdzaj na Crowdin + Brak kompatybilnych aplikacji do otrzymania eksportowanych transakcji! + Przenieś... + Duplikuj Bieżący miesiąc Ostatnie 3 miesiące diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index eb9abd509..300f2335f 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -380,8 +380,6 @@ Neste processo não serão recolhidas informações do utilizador! Não existem aplicações compatíveis para receber as transações exportadas! Mover... Duplicar - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s Mês actual Últimos 3 meses diff --git a/app/src/main/res/values-ro-rRO/strings.xml b/app/src/main/res/values-ro-rRO/strings.xml index 39d2ad4e3..58d71312c 100644 --- a/app/src/main/res/values-ro-rRO/strings.xml +++ b/app/src/main/res/values-ro-rRO/strings.xml @@ -390,8 +390,6 @@ No compatible apps to receive the exported transactions! Move... Duplicate - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s Current month Last 3 months diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index 3294518db..7675c5eaa 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -388,8 +388,6 @@ Не совместимых приложений, чтобы получить экспортированные транзакции! Переместить... Повтор - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s Текущий месяц Последний квартал diff --git a/app/src/main/res/values-sv-rSE/strings.xml b/app/src/main/res/values-sv-rSE/strings.xml index fdb319544..be27a04cf 100644 --- a/app/src/main/res/values-sv-rSE/strings.xml +++ b/app/src/main/res/values-sv-rSE/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -199,7 +200,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent @@ -385,8 +389,6 @@ No compatible apps to receive the exported transactions! Move... Duplicate - Invalid exchange rate - e.g. 1 %1$s = x.xx %2$s Current month Last 3 months diff --git a/app/src/main/res/values-vi-rVN/strings.xml b/app/src/main/res/values-vi-rVN/strings.xml index 47619e9c8..c57a26868 100644 --- a/app/src/main/res/values-vi-rVN/strings.xml +++ b/app/src/main/res/values-vi-rVN/strings.xml @@ -168,6 +168,7 @@ File format to use by default when exporting transactions Export transactions… Recurrence + Imbalance Exporting transactions No recurring transactions to display. @@ -198,7 +199,10 @@ OFX XML + Select a Color + + Account Color & Type Delete sub-accounts Recent diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index dbc471266..8d4d232a7 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -15,9 +15,9 @@ See the License for the specific language governing permissions and limitations under the License. --> - - 创建账户 - 编辑账户 + + 创建科目 + 修改科目 信息 导出... 为科目增加交易 @@ -166,6 +166,7 @@ 导出交易信息时使用的文件格式。 导出交易… 重复 + 不平衡的 正在导出交易信息 没有要显示的计划交易 @@ -196,7 +197,10 @@ OFX XML + 选择一种颜色 + + 科目颜色和类型 删除子科目 最近的 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index d3ac600e3..629a37e16 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -389,7 +389,7 @@ Share ideas, discuss changes or report problems Translate or proof-read on CrowdIn No compatible apps to receive the exported transactions! - Move... + Move… Duplicate Invalid exchange rate e.g. 1 %1$s = x.xx %2$s From c0d00e1e5ca20332f922540430f25dee343d1196 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Tue, 19 Apr 2016 10:15:12 +0200 Subject: [PATCH 15/15] Update version number and changelog for v2.0.7 release --- CHANGELOG.md | 5 +++++ app/build.gradle | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dff54522..19ba4c4b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ Change Log =============================================================================== +Version 2.0.7 *(2016-04-20)* +---------------------------- +* Fixed: Currency exchange rate does not accept very small rates (> 2 decimal places) +* Improved: Updated translations for Japanese, Polish, French, + Version 2.0.6 *(2016-02-20)* ---------------------------- * Fixed: Saving transaction gets slower with increase in size of database diff --git a/app/build.gradle b/app/build.gradle index e381225ef..f4613f4e6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,8 +5,8 @@ apply plugin: 'io.fabric' def versionMajor = 2 def versionMinor = 0 -def versionPatch = 6 -def versionBuild = 3 +def versionPatch = 7 +def versionBuild = 0 def buildTime() { def df = new SimpleDateFormat("yyyyMMdd HH:mm 'UTC'")