From ad62cec2ac198bc2951e306ca05f754b51f9c357 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Mon, 22 Sep 2014 23:29:33 +0800 Subject: [PATCH 01/30] Disable editing for multi-currency transactions --- .../gnucash/android/db/DatabaseAdapter.java | 3 ++- .../android/db/TransactionsDbAdapter.java | 18 +++++++++++++++ .../transaction/TransactionFormFragment.java | 23 +++++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/db/DatabaseAdapter.java b/app/src/org/gnucash/android/db/DatabaseAdapter.java index 24bf926d0..f6d756fe2 100644 --- a/app/src/org/gnucash/android/db/DatabaseAdapter.java +++ b/app/src/org/gnucash/android/db/DatabaseAdapter.java @@ -141,7 +141,8 @@ private void createTempView() { // ) , // 2 // ) as trans_acct_a_uid , - // TOTAL ( CASE WHEN splits_type = 'DEBIT' THEN splits_amount ELSE - splits_amount END ) AS trans_acct_balance + // TOTAL ( CASE WHEN splits_type = 'DEBIT' THEN splits_amount ELSE - splits_amount END ) AS trans_acct_balance, + // COUNT ( DISTINCT accounts_currency ) as trans_currency_count // FROM trans_split_acct GROUP BY transactions_uid // // This temporary view would pick one Account_UID for each diff --git a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java index e27d7269d..69675d118 100644 --- a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java +++ b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java @@ -597,4 +597,22 @@ public void scheduleTransaction(Transaction recurringTransaction) { public Transaction getTransaction(String transactionUID) { return getTransaction(getID(transactionUID)); } + + public int getNumCurrencies(String transactionUID) { + Cursor cursor = mDb.query("trans_extra_info", + new String[]{"trans_currency_count"}, + "trans_acct_t_uid=?", + new String[]{transactionUID}, + null, null, null); + int numCurrencies = 0; + try { + if (cursor.moveToFirst()) { + numCurrencies = cursor.getInt(0); + } + } + finally { + cursor.close(); + } + return numCurrencies; + } } diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index e8b9b1b3b..7240f4147 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -159,6 +159,11 @@ public class TransactionFormFragment extends SherlockFragment implements */ private boolean mUseDoubleEntry; + /** + * Flag to not if the transaction involves multiple currency + */ + private boolean mMultiCurrency; + /** * The AccountType of the account to which this transaction belongs. * Used for determining the accounting rules for credits and debits @@ -323,6 +328,7 @@ public void onItemClick(AdapterView adapterView, View view, int position, lon * This method is called if the fragment is used for editing a transaction */ private void initializeViewsWithTransaction(){ + mMultiCurrency = mTransactionsDbAdapter.getNumCurrencies(mTransaction.getUID()) > 1; mDescriptionEditText.setText(mTransaction.getDescription()); mTransactionTypeButton.setAccountType(mAccountType); @@ -360,6 +366,23 @@ private void initializeViewsWithTransaction(){ mCurrencyTextView.setText(accountCurrency.getSymbol()); setSelectedRecurrenceOption(); + if (mMultiCurrency) { + enableControls(false); + } + } + + private void enableControls(boolean b) { + mDescriptionEditText.setEnabled(b); + mNotesEditText.setEnabled(b); + mDateTextView.setEnabled(b); + mTimeTextView.setEnabled(b); + mAmountEditText.setEnabled(b); + mCurrencyTextView.setEnabled(b); + mTransactionTypeButton.setEnabled(b); + mDoubleAccountSpinner.setEnabled(b); + // the next is always enabled, so the user can check the detailed info of splits + // mOpenSplitsButton; + mRecurringTransactionSpinner.setEnabled(b); } private void setAmountEditViewVisible(int visibility) { From 218de7536e12da81ab373055e5116f775a843c8e Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Mon, 22 Sep 2014 23:36:25 +0800 Subject: [PATCH 02/30] refuse to modify when saving --- .../android/ui/transaction/TransactionFormFragment.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 7240f4147..5782c6ca9 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -722,7 +722,11 @@ public boolean onOptionsItemSelected(MenuItem item) { return true; case R.id.menu_save: - if (mAmountEditText.getText().length() == 0){ + if (mMultiCurrency) { + Toast.makeText(getActivity(), "Multi-currency transactions cannot be modified", Toast.LENGTH_LONG).show(); + finish(); + } + else if (mAmountEditText.getText().length() == 0) { Toast.makeText(getActivity(), R.string.toast_transanction_amount_required, Toast.LENGTH_SHORT).show(); } else saveNewTransaction(); From fcc72cd06fe1356c254c74e8b9db2c19a279d665 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Tue, 23 Sep 2014 21:48:53 +0800 Subject: [PATCH 03/30] Put toast string to resource --- app/res/values/strings.xml | 1 + .../gnucash/android/ui/transaction/TransactionFormFragment.java | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml index 2c5b8ed56..d6d0c3943 100644 --- a/app/res/values/strings.xml +++ b/app/res/values/strings.xml @@ -325,6 +325,7 @@ Dismiss Enter an amount to save the transaction + Multi-currency transactions cannot be modified Import GnuCash Accounts Import Accounts An error occurred while importing the GnuCash accounts diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 5782c6ca9..533f705cb 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -723,7 +723,7 @@ public boolean onOptionsItemSelected(MenuItem item) { case R.id.menu_save: if (mMultiCurrency) { - Toast.makeText(getActivity(), "Multi-currency transactions cannot be modified", Toast.LENGTH_LONG).show(); + Toast.makeText(getActivity(), R.string.toast_error_edit_multi_currency_transaction, Toast.LENGTH_LONG).show(); finish(); } else if (mAmountEditText.getText().length() == 0) { From 85976982dc2a21568e66704fef7f744eac6cdbb0 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Tue, 23 Sep 2014 21:51:53 +0800 Subject: [PATCH 04/30] Refuse to change account multi-currency transaction --- .../transaction/TransactionFormFragment.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 533f705cb..11a7bc7aa 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -567,19 +567,23 @@ public void run() { * Callback when the account in the navigation bar is changed by the user * @param newAccountId Database record ID of the newly selected account */ - public void onAccountChanged(long newAccountId){ - AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(getActivity()); - String currencyCode = accountsDbAdapter.getCurrencyCode(newAccountId); - Currency currency = Currency.getInstance(currencyCode); - mCurrencyTextView.setText(currency.getSymbol(Locale.getDefault())); + public void onAccountChanged(long newAccountId) { + if (mMultiCurrency) { + Toast.makeText(getActivity(), R.string.toast_error_edit_multi_currency_transaction, Toast.LENGTH_LONG).show(); + return; + } + AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(getActivity()); + String currencyCode = accountsDbAdapter.getCurrencyCode(newAccountId); + Currency currency = Currency.getInstance(currencyCode); + mCurrencyTextView.setText(currency.getSymbol(Locale.getDefault())); mAccountType = accountsDbAdapter.getAccountType(newAccountId); mTransactionTypeButton.setAccountType(mAccountType); - updateTransferAccountsList(); + updateTransferAccountsList(); accountsDbAdapter.close(); - } + } /** * Collects information from the fragment views and uses it to create From 53e3522a91ce5415bc9bf163b138d1ea0600db60 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Tue, 23 Sep 2014 23:31:19 +0800 Subject: [PATCH 05/30] Try to disable split edition for multi-currency transactions --- .../dialog/SplitEditorDialogFragment.java | 57 +++++++++++++++---- 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java index 02e1e7804..36aba2db6 100644 --- a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java @@ -69,6 +69,8 @@ public class SplitEditorDialogFragment extends DialogFragment { private BigDecimal mBaseAmount = BigDecimal.ZERO; private List mRemovedSplitUIDs = new ArrayList(); + + private boolean mMultiCurrency = false; /** * Create and return a new instance of the fragment with the appropriate paramenters * @param baseAmountString String with base amount which is being split @@ -129,8 +131,37 @@ public void onActivityCreated(Bundle savedInstanceState) { } private void loadSplitViews(List splitList) { + Currency currency = null; for (Split split : splitList) { addSplitView(split); + if (currency == null) { + currency = split.getAmount().getCurrency(); + } + else if (currency != split.getAmount().getCurrency()) { + mMultiCurrency = true; + } + } + if (mMultiCurrency) { + enableAllControls(false); + } + } + + private void enableAllControls(boolean b) { + for (View splitView : mSplitItemViewList) { + EditText splitMemoEditText = (EditText) splitView.findViewById(R.id.input_split_memo); + final EditText splitAmountEditText = (EditText) splitView.findViewById(R.id.input_split_amount); + ImageButton removeSplitButton = (ImageButton) splitView.findViewById(R.id.btn_remove_split); + Spinner accountsSpinner = (Spinner) splitView.findViewById(R.id.input_accounts_spinner); + final TextView splitCurrencyTextView = (TextView) splitView.findViewById(R.id.split_currency_symbol); + final TextView splitUidTextView = (TextView) splitView.findViewById(R.id.split_uid); + final TransactionTypeToggleButton splitTypeButton = (TransactionTypeToggleButton) splitView.findViewById(R.id.btn_split_type); + splitMemoEditText.setEnabled(b); + splitAmountEditText.setEnabled(b); + removeSplitButton.setEnabled(b); + accountsSpinner.setEnabled(b); + splitCurrencyTextView.setEnabled(b); + splitUidTextView.setEnabled(b); + splitTypeButton.setEnabled(b); } } @@ -260,9 +291,13 @@ public void onClick(View view) { mSaveButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - List splitList = extractSplitsFromView(); - ((TransactionFormFragment) getTargetFragment()).setSplitList(splitList, mRemovedSplitUIDs); - + if (mMultiCurrency) { + Toast.makeText(getActivity(), R.string.toast_error_edit_multi_currency_transaction, Toast.LENGTH_LONG).show(); + } + else { + List splitList = extractSplitsFromView(); + ((TransactionFormFragment) getTargetFragment()).setSplitList(splitList, mRemovedSplitUIDs); + } dismiss(); } }); @@ -309,15 +344,15 @@ private void updateTotal(){ List splitList = extractSplitsFromView(); String currencyCode = mAccountsDbAdapter.getCurrencyCode(mAccountId); Money splitSum = Money.createZeroInstance(currencyCode); - - for (Split split : splitList) { - Money amount = split.getAmount().absolute(); - if (split.getType() == TransactionType.DEBIT) - splitSum = splitSum.subtract(amount); - else - splitSum = splitSum.add(amount); + if (!mMultiCurrency) { + for (Split split : splitList) { + Money amount = split.getAmount().absolute(); + if (split.getType() == TransactionType.DEBIT) + splitSum = splitSum.subtract(amount); + else + splitSum = splitSum.add(amount); + } } - TransactionsActivity.displayBalance(mImbalanceTextView, splitSum); } From 0eee34e369600457b6a6bbddde7ee5162e74bf2e Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 24 Sep 2014 20:44:37 +0800 Subject: [PATCH 06/30] Show correct transfer account --- .../ui/transaction/TransactionFormFragment.java | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 11a7bc7aa..48f3f559c 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -224,9 +224,6 @@ public void onActivityCreated(Bundle savedInstanceState) { mAccountsDbAdapter = new AccountsDbAdapter(getActivity()); mAccountType = mAccountsDbAdapter.getAccountType(mAccountUID); - //updateTransferAccountsList must only be called after initializing mAccountsDbAdapter - updateTransferAccountsList(); - ArrayAdapter recurrenceAdapter = ArrayAdapter.createFromResource(getActivity(), R.array.recurrence_period_strings, android.R.layout.simple_spinner_item); recurrenceAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); @@ -235,6 +232,13 @@ public void onActivityCreated(Bundle savedInstanceState) { String transactionUID = getArguments().getString(UxArgument.SELECTED_TRANSACTION_UID); mTransactionsDbAdapter = new TransactionsDbAdapter(getActivity()); mTransaction = mTransactionsDbAdapter.getTransaction(transactionUID); + if (mTransaction != null) { + mMultiCurrency = mTransactionsDbAdapter.getNumCurrencies(mTransaction.getUID()) > 1; + } + + //updateTransferAccountsList must only be called after initializing mAccountsDbAdapter + // it needs mMultiCurrency to be properly initialized + updateTransferAccountsList(); mDoubleAccountSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override @@ -328,7 +332,6 @@ public void onItemClick(AdapterView adapterView, View view, int position, lon * This method is called if the fragment is used for editing a transaction */ private void initializeViewsWithTransaction(){ - mMultiCurrency = mTransactionsDbAdapter.getNumCurrencies(mTransaction.getUID()) > 1; mDescriptionEditText.setText(mTransaction.getDescription()); mTransactionTypeButton.setAccountType(mAccountType); @@ -448,8 +451,8 @@ private void updateTransferAccountsList(){ String accountUID = ((TransactionsActivity)getActivity()).getCurrentAccountUID(); String conditions = "(" + DatabaseSchema.AccountEntry.COLUMN_UID + " != '" + accountUID - + "' AND " + DatabaseSchema.AccountEntry.COLUMN_CURRENCY + " = '" + mAccountsDbAdapter.getCurrencyCode(accountUID) - + "' AND " + DatabaseSchema.AccountEntry.COLUMN_UID + " != '" + mAccountsDbAdapter.getGnuCashRootAccountUID() + + "' AND " + (mMultiCurrency ? "" : (DatabaseSchema.AccountEntry.COLUMN_CURRENCY + " = '" + mAccountsDbAdapter.getCurrencyCode(accountUID) + + "' AND ")) + DatabaseSchema.AccountEntry.COLUMN_UID + " != '" + mAccountsDbAdapter.getGnuCashRootAccountUID() + "' AND " + DatabaseSchema.AccountEntry.COLUMN_PLACEHOLDER + " = 0" + ")"; From 9a68423b5c8b0a3242c5d6ea7bd45c655521d16b Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 24 Sep 2014 21:40:28 +0800 Subject: [PATCH 07/30] Keep currency for transaction splits --- app/src/org/gnucash/android/model/Transaction.java | 5 +---- .../android/ui/transaction/TransactionFormFragment.java | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/org/gnucash/android/model/Transaction.java b/app/src/org/gnucash/android/model/Transaction.java index ecdfe1ae8..8e1cddc30 100644 --- a/app/src/org/gnucash/android/model/Transaction.java +++ b/app/src/org/gnucash/android/model/Transaction.java @@ -185,10 +185,7 @@ public List getSplits(String accountUID){ * @param splitList List of splits for this transaction */ public void setSplits(List splitList){ - mSplitList.clear(); - for (Split split : splitList) { - addSplit(split); - } + mSplitList = splitList; } /** diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 48f3f559c..5eda9bac3 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -484,7 +484,7 @@ private void openSplitEditor(){ } else { Money biggestAmount = Money.createZeroInstance(mTransaction.getCurrencyCode()); for (Split split : mTransaction.getSplits()) { - if (split.getAmount().compareTo(biggestAmount) > 0) + if (split.getAmount().asBigDecimal().compareTo(biggestAmount.asBigDecimal()) > 0) biggestAmount = split.getAmount(); } baseAmountString = biggestAmount.toPlainString(); From 4745dea1afd48f298f1aaaab7740d11cf468ce87 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 24 Sep 2014 21:49:25 +0800 Subject: [PATCH 08/30] reject add split; show splits own currency --- .../ui/transaction/dialog/SplitEditorDialogFragment.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java index 36aba2db6..89e9f395e 100644 --- a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java @@ -227,7 +227,7 @@ public void onClick(View view) { updateTransferAccountsList(accountsSpinner); accountsSpinner.setOnItemSelectedListener(new TypeButtonLabelUpdater(splitTypeButton)); - Currency accountCurrency = Currency.getInstance(mAccountsDbAdapter.getCurrencyCode(mAccountId)); + Currency accountCurrency = Currency.getInstance(mAccountsDbAdapter.getCurrencyCode(split.getAccountUID())); splitCurrencyTextView.setText(accountCurrency.getSymbol()); splitTypeButton.setAmountFormattingListener(splitAmountEditText, splitCurrencyTextView); splitTypeButton.setChecked(mBaseAmount.signum() > 0); @@ -305,7 +305,12 @@ public void onClick(View view) { mAddSplit.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - addSplitView(null); + if (mMultiCurrency) { + Toast.makeText(getActivity(), R.string.toast_error_edit_multi_currency_transaction, Toast.LENGTH_LONG).show(); + } + else { + addSplitView(null); + } } }); } From a90349e356a79d5df64be56695e8a4f715e46798 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 24 Sep 2014 22:20:59 +0800 Subject: [PATCH 09/30] show correct split account --- .../dialog/SplitEditorDialogFragment.java | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java index 89e9f395e..75bde5563 100644 --- a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java @@ -105,13 +105,24 @@ public void onActivityCreated(Bundle savedInstanceState) { getDialog().setTitle("Transaction splits"); - initArgs(); mSplitItemViewList = new ArrayList(); mSplitsDbAdapter = new SplitsDbAdapter(getActivity()); //we are editing splits for a new transaction. // But the user may have already created some splits before. Let's check List splitList = ((TransactionFormFragment) getTargetFragment()).getSplitList(); + { + Currency currency = null; + for (Split split : splitList) { + if (currency == null) { + currency = split.getAmount().getCurrency(); + } else if (currency != split.getAmount().getCurrency()) { + mMultiCurrency = true; + } + } + } + + initArgs(); if (!splitList.isEmpty()) { //aha! there are some splits. Let's load those instead loadSplitViews(splitList); @@ -131,15 +142,8 @@ public void onActivityCreated(Bundle savedInstanceState) { } private void loadSplitViews(List splitList) { - Currency currency = null; for (Split split : splitList) { addSplitView(split); - if (currency == null) { - currency = split.getAmount().getCurrency(); - } - else if (currency != split.getAmount().getCurrency()) { - mMultiCurrency = true; - } } if (mMultiCurrency) { enableAllControls(false); @@ -191,8 +195,8 @@ private void initArgs() { mBaseAmount = new BigDecimal(args.getString(UxArgument.AMOUNT_STRING)); String conditions = "(" //+ AccountEntry._ID + " != " + mAccountId + " AND " - + DatabaseSchema.AccountEntry.COLUMN_CURRENCY + " = '" + mAccountsDbAdapter.getCurrencyCode(mAccountId) - + "' AND " + DatabaseSchema.AccountEntry.COLUMN_UID + " != '" + mAccountsDbAdapter.getGnuCashRootAccountUID() + + (mMultiCurrency ? "" : (DatabaseSchema.AccountEntry.COLUMN_CURRENCY + " = '" + mAccountsDbAdapter.getCurrencyCode(mAccountId) + + "' AND ")) + DatabaseSchema.AccountEntry.COLUMN_UID + " != '" + mAccountsDbAdapter.getGnuCashRootAccountUID() + "' AND " + DatabaseSchema.AccountEntry.COLUMN_PLACEHOLDER + " = 0" + ")"; mCursor = mAccountsDbAdapter.fetchAccountsOrderedByFullName(conditions); From 2ce1769312dc173595b1d7d7b6d4e71790d03d33 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 24 Sep 2014 23:38:24 +0800 Subject: [PATCH 10/30] Account Currency edit restriction --- .../gnucash/android/db/AccountsDbAdapter.java | 23 +++++++++++++++++++ .../gnucash/android/db/DatabaseAdapter.java | 2 +- .../ui/account/AccountFormFragment.java | 7 ++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/org/gnucash/android/db/AccountsDbAdapter.java index 33fcf4845..3ce9583d9 100644 --- a/app/src/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/org/gnucash/android/db/AccountsDbAdapter.java @@ -25,6 +25,7 @@ import android.text.TextUtils; import android.util.Log; +import android.support.annotation.NonNull; import org.gnucash.android.R; import org.gnucash.android.app.GnuCashApplication; import org.gnucash.android.model.*; @@ -1322,4 +1323,26 @@ public int deleteAllRecords(){ return mDb.delete(AccountEntry.TABLE_NAME, null, null); } + public int getTransactionMaxSplitNum(@NonNull String accountUID) { + Cursor cursor = mDb.query("trans_extra_info", + new String[]{"MAX(trans_split_count)"}, + "trans_acct_t_uid IN ( SELECT DISTINCT " + TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID + + " FROM trans_split_acct WHERE " + AccountEntry.TABLE_NAME + "_" + AccountEntry.COLUMN_UID + + " = ? )", + new String[]{accountUID}, + null, + null, + null + ); + try { + if (cursor.moveToFirst()) { + return (int)cursor.getLong(0); + } else { + return 0; + } + } + finally { + cursor.close(); + } + } } diff --git a/app/src/org/gnucash/android/db/DatabaseAdapter.java b/app/src/org/gnucash/android/db/DatabaseAdapter.java index 24bf926d0..b5965a6be 100644 --- a/app/src/org/gnucash/android/db/DatabaseAdapter.java +++ b/app/src/org/gnucash/android/db/DatabaseAdapter.java @@ -164,7 +164,7 @@ private void createTempView() { SplitEntry.COLUMN_AMOUNT + " ELSE - " + SplitEntry.TABLE_NAME + "_" + SplitEntry.COLUMN_AMOUNT + " END ) AS trans_acct_balance , COUNT ( DISTINCT " + AccountEntry.TABLE_NAME + "_" + AccountEntry.COLUMN_CURRENCY + - " ) AS trans_currency_count FROM trans_split_acct " + + " ) AS trans_currency_count , COUNT (*) AS trans_split_count FROM trans_split_acct " + " GROUP BY " + TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID ); } diff --git a/app/src/org/gnucash/android/ui/account/AccountFormFragment.java b/app/src/org/gnucash/android/ui/account/AccountFormFragment.java index 91d5136ad..1d8b6573e 100644 --- a/app/src/org/gnucash/android/ui/account/AccountFormFragment.java +++ b/app/src/org/gnucash/android/ui/account/AccountFormFragment.java @@ -27,6 +27,8 @@ import android.graphics.Color; import android.os.Bundle; import android.preference.PreferenceManager; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.support.v4.app.FragmentManager; import android.support.v4.widget.SimpleCursorAdapter; import android.text.TextUtils; @@ -351,6 +353,11 @@ private void initializeViewsWithAccount(Account account){ String currencyCode = account.getCurrency().getCurrencyCode(); setSelectedCurrency(currencyCode); + if (mAccountsDbAdapter.getTransactionMaxSplitNum(mAccount.getUID()) > 1) + { + mCurrencySpinner.setEnabled(false); + } + mNameEditText.setText(account.getName()); if (mUseDoubleEntry) { From a33798a0bdf6268b41997bd678ca925fec8fc44e Mon Sep 17 00:00:00 2001 From: Oleg Kosmakov Date: Wed, 24 Sep 2014 19:19:56 +0300 Subject: [PATCH 11/30] Extracted string resources from split transaction dialog --- app/res/layout/dialog_split_editor.xml | 4 ++-- app/res/values/strings.xml | 3 +++ .../ui/transaction/dialog/SplitEditorDialogFragment.java | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/res/layout/dialog_split_editor.xml b/app/res/layout/dialog_split_editor.xml index 772b86e54..3b46a1a31 100644 --- a/app/res/layout/dialog_split_editor.xml +++ b/app/res/layout/dialog_split_editor.xml @@ -55,7 +55,7 @@ limitations under the License. android:layout_height="match_parent" android:textAppearance="?android:attr/textAppearanceSmall" android:gravity="center_vertical" - android:text="Imbalance:"/> + android:text="@string/label_imbalance"/> + android:text="@string/btn_add_split"/> \ No newline at end of file diff --git a/app/res/values/strings.xml b/app/res/values/strings.xml index 3318d3170..4cb565ba2 100644 --- a/app/res/values/strings.xml +++ b/app/res/values/strings.xml @@ -653,4 +653,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java index 59875cd24..b21b1e4d5 100644 --- a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java @@ -101,7 +101,7 @@ public void onActivityCreated(Bundle savedInstanceState) { getDialog().getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); - getDialog().setTitle("Transaction splits"); + getDialog().setTitle(R.string.title_transaction_splits); initArgs(); mSplitItemViewList = new ArrayList(); From 78844265fc02509926a262e701731f45aff22e56 Mon Sep 17 00:00:00 2001 From: Ngewi Fet Date: Wed, 24 Sep 2014 21:10:04 +0200 Subject: [PATCH 12/30] Added newly extracted strings to all supported locales --- app/res/values-de/strings.xml | 3 +++ app/res/values-el/strings.xml | 3 +++ app/res/values-es-rMX/strings.xml | 3 +++ app/res/values-es/strings.xml | 3 +++ app/res/values-fr/strings.xml | 3 +++ app/res/values-hu/strings.xml | 3 +++ app/res/values-it/strings.xml | 3 +++ app/res/values-nb/strings.xml | 3 +++ app/res/values-nl/strings.xml | 3 +++ app/res/values-pt-rBR/strings.xml | 3 +++ app/res/values-ru/strings.xml | 3 +++ app/res/values-zh/strings.xml | 3 +++ 12 files changed, 36 insertions(+) diff --git a/app/res/values-de/strings.xml b/app/res/values-de/strings.xml index 7d7519ace..236533fa6 100644 --- a/app/res/values-de/strings.xml +++ b/app/res/values-de/strings.xml @@ -416,4 +416,7 @@ Möglichkeit aktivieren, den aktuellen Saldo als neuen Anfangsbestand nach dem Löschen der Buchungen zu übernehmen Saldo als neuen Anfangsbestand übernehmen + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-el/strings.xml b/app/res/values-el/strings.xml index fd98866de..488a07c22 100644 --- a/app/res/values-el/strings.xml +++ b/app/res/values-el/strings.xml @@ -434,4 +434,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-es-rMX/strings.xml b/app/res/values-es-rMX/strings.xml index 26833c097..396f21d02 100644 --- a/app/res/values-es-rMX/strings.xml +++ b/app/res/values-es-rMX/strings.xml @@ -419,4 +419,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-es/strings.xml b/app/res/values-es/strings.xml index 73ccf00ec..abd64690c 100644 --- a/app/res/values-es/strings.xml +++ b/app/res/values-es/strings.xml @@ -416,4 +416,7 @@ Seleccionar para guardar el saldo actual (antes de borrar las transacciones) como nuevo saldo de apertura despues de borrar las transacciones Guardar saldos de apertura + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-fr/strings.xml b/app/res/values-fr/strings.xml index f5a2d5f8b..c9e281cac 100644 --- a/app/res/values-fr/strings.xml +++ b/app/res/values-fr/strings.xml @@ -416,4 +416,7 @@ Permet d\'enregistrer le solde du compte courant (avant la suppression des transactions) comme le nouveau solde d\'ouverture après la suppression des transactions Enregistrer les soldes des comptes d\'ouverture + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-hu/strings.xml b/app/res/values-hu/strings.xml index 2314ab776..17698a974 100644 --- a/app/res/values-hu/strings.xml +++ b/app/res/values-hu/strings.xml @@ -420,4 +420,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split \ No newline at end of file diff --git a/app/res/values-it/strings.xml b/app/res/values-it/strings.xml index b48826565..95a6a3c41 100644 --- a/app/res/values-it/strings.xml +++ b/app/res/values-it/strings.xml @@ -420,4 +420,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-nb/strings.xml b/app/res/values-nb/strings.xml index a0e403363..c38b77400 100644 --- a/app/res/values-nb/strings.xml +++ b/app/res/values-nb/strings.xml @@ -416,4 +416,7 @@ Egenkapital Merk for å lagre gjeldende konto balanse (før sletting) som ny inngående balanse (etter sletting av transaksjoner). Lagre inngående balanser + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-nl/strings.xml b/app/res/values-nl/strings.xml index ddc904d07..4b1cf26c7 100644 --- a/app/res/values-nl/strings.xml +++ b/app/res/values-nl/strings.xml @@ -421,4 +421,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-pt-rBR/strings.xml b/app/res/values-pt-rBR/strings.xml index 89c6a37b2..1d3842c1b 100644 --- a/app/res/values-pt-rBR/strings.xml +++ b/app/res/values-pt-rBR/strings.xml @@ -419,4 +419,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-ru/strings.xml b/app/res/values-ru/strings.xml index 607837484..868f147d7 100644 --- a/app/res/values-ru/strings.xml +++ b/app/res/values-ru/strings.xml @@ -420,4 +420,7 @@ Включите чтобы сохранить текущий баланс (перед удалением проводок) как новое начальное сальдо после их удаления Сохранять начальное сальдо счетов + Transaction splits + Imbalance: + Add split diff --git a/app/res/values-zh/strings.xml b/app/res/values-zh/strings.xml index fc21bbbdf..48c6158ed 100644 --- a/app/res/values-zh/strings.xml +++ b/app/res/values-zh/strings.xml @@ -414,4 +414,7 @@ Enable to save the current account balance (before deleting transactions) as new opening balance after deleting transactions Save account opening balances + Transaction splits + Imbalance: + Add split From 79b8890dd2f12026d80f6285bf4b0aac8867b34b Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Thu, 2 Oct 2014 15:35:22 +0800 Subject: [PATCH 13/30] Rewrite upgrade db versin 6 to 7 --- .../gnucash/android/db/DatabaseHelper.java | 108 +++++++++++++++--- 1 file changed, 89 insertions(+), 19 deletions(-) diff --git a/app/src/org/gnucash/android/db/DatabaseHelper.java b/app/src/org/gnucash/android/db/DatabaseHelper.java index 7a95bd6c0..c9c6c00a7 100644 --- a/app/src/org/gnucash/android/db/DatabaseHelper.java +++ b/app/src/org/gnucash/android/db/DatabaseHelper.java @@ -24,6 +24,7 @@ import android.util.Log; import android.widget.Toast; import org.gnucash.android.model.AccountType; +import org.gnucash.android.model.Transaction; import static org.gnucash.android.db.DatabaseSchema.*; @@ -33,6 +34,7 @@ * @author Ngewi Fet * */ +@SuppressWarnings("deprecation") public class DatabaseHelper extends SQLiteOpenHelper { /** @@ -222,27 +224,95 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion == 6 && newVersion >= DatabaseSchema.SPLITS_DB_VERSION){ Log.i(LOG_TAG, "Upgrading database to version 7"); - - //for users who do not have double-entry activated, we create imbalance accounts for their splits - //TODO: Enable when we can hide imbalance accounts from user -// List currencies = MigrationHelper.getCurrencies(db); -// AccountsDbAdapter accountsDbAdapter = new AccountsDbAdapter(db); -// for (Currency currency : currencies) { -// accountsDbAdapter.getOrCreateImbalanceAccountUID(currency); -// } - + db.beginTransaction(); try { - String filepath = MigrationHelper.exportGnucashXML(db); - - dropAllDatabaseTables(db); - createDatabaseTables(db); - - MigrationHelper.importGnucashXML(db, filepath); - } catch (Exception e){ - Toast.makeText(mContext, "Error upgrading database.\n" + e.getMessage(), Toast.LENGTH_LONG).show(); - throw new RuntimeException(e); + // backup transaction table + db.execSQL("ALTER TABLE " + TransactionEntry.TABLE_NAME + " RENAME TO " + TransactionEntry.TABLE_NAME + "_bak"); + // create new transaction table + db.execSQL("create table " + TransactionEntry.TABLE_NAME + " (" + + TransactionEntry._ID + " integer primary key autoincrement, " + + TransactionEntry.COLUMN_UID + " varchar(255) not null, " + + TransactionEntry.COLUMN_DESCRIPTION + " varchar(255), " + + TransactionEntry.COLUMN_NOTES + " text, " + + TransactionEntry.COLUMN_TIMESTAMP + " integer not null, " + + TransactionEntry.COLUMN_EXPORTED + " tinyint default 0, " + + TransactionEntry.COLUMN_CURRENCY + " varchar(255) not null, " + + TransactionEntry.COLUMN_RECURRENCE_PERIOD + " integer default 0, " + + "UNIQUE (" + TransactionEntry.COLUMN_UID + ") " + + ");"); + // initialize new transaction table wiht data from old table + db.execSQL("INSERT INTO " + TransactionEntry.TABLE_NAME + " ( " + + TransactionEntry._ID + " , " + + TransactionEntry.COLUMN_UID + " , " + + TransactionEntry.COLUMN_DESCRIPTION + " , " + + TransactionEntry.COLUMN_NOTES + " , " + + TransactionEntry.COLUMN_TIMESTAMP + " , " + + TransactionEntry.COLUMN_EXPORTED + " , " + + TransactionEntry.COLUMN_CURRENCY + " , " + + TransactionEntry.COLUMN_RECURRENCE_PERIOD + " ) SELECT " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry._ID + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_UID + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_DESCRIPTION + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_NOTES + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_TIMESTAMP + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_EXPORTED + " , " + + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_CURRENCY + " , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_RECURRENCE_PERIOD + + " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME + + " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid == " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID + ); + // create split table + db.execSQL("CREATE TABLE " + SplitEntry.TABLE_NAME + " (" + + SplitEntry._ID + " integer primary key autoincrement, " + + SplitEntry.COLUMN_UID + " varchar(255) not null, " + + SplitEntry.COLUMN_MEMO + " text, " + + SplitEntry.COLUMN_TYPE + " varchar(255) not null, " + + SplitEntry.COLUMN_AMOUNT + " varchar(255) not null, " + + SplitEntry.COLUMN_ACCOUNT_UID + " varchar(255) not null, " + + SplitEntry.COLUMN_TRANSACTION_UID + " varchar(255) not null, " + + "FOREIGN KEY (" + SplitEntry.COLUMN_ACCOUNT_UID + ") REFERENCES " + AccountEntry.TABLE_NAME + " (" + AccountEntry.COLUMN_UID + "), " + + "FOREIGN KEY (" + SplitEntry.COLUMN_TRANSACTION_UID + ") REFERENCES " + TransactionEntry.TABLE_NAME + " (" + TransactionEntry.COLUMN_UID + "), " + + "UNIQUE (" + SplitEntry.COLUMN_UID + ") " + + ");"); + // Initialize split table with data from backup transaction table + // New split table is initialized after the new transaction table as the + // foreign key constraint will stop any data from being inserted + // If new split table is created before the backup is made, the foreign key + // constraint will be rewritten to refer to the backup transaction table + db.execSQL("INSERT INTO " + SplitEntry.TABLE_NAME + " ( " + + SplitEntry.COLUMN_UID + " , " + + SplitEntry.COLUMN_TYPE + " , " + + SplitEntry.COLUMN_AMOUNT + " , " + + SplitEntry.COLUMN_ACCOUNT_UID + " , " + + SplitEntry.COLUMN_TRANSACTION_UID + " ) SELECT " + // _ID, autogenerated + + "LOWER(HEX(RANDOMBLOB(16))) , " + // COLUMN_MEMO, empty + + "CASE WHEN " + TransactionEntry.TABLE_NAME + "_bak.type IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END ELSE CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END END , " + + "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , " + + TransactionEntry.TABLE_NAME + "_bak.account_uid , " + + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_UID + + " FROM " + TransactionEntry.TABLE_NAME + "_bak UNION SELECT " + // _ID, autogenerated + + "LOWER(HEX(RANDOMBLOB(16))) AS " + SplitEntry.COLUMN_UID + " , " + // COLUMN_MEMO, empty + + "CASE WHEN " + TransactionEntry.TABLE_NAME + "_bak.type IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END ELSE CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END END , " + + "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , " + + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " , " + + TransactionEntry.TABLE_NAME + "_baK." + TransactionEntry.COLUMN_UID + + " FROM " + TransactionEntry.TABLE_NAME + "_bak WHERE " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " IS NOT NULL" + ); + // drop backup transaction table + db.execSQL("DROP TABLE " + TransactionEntry.TABLE_NAME + "_bak"); + db.setTransactionSuccessful(); + oldVersion = DatabaseSchema.SPLITS_DB_VERSION; + } finally { + db.endTransaction(); } - oldVersion = DatabaseSchema.SPLITS_DB_VERSION; } } From 84859f24d7d602f2d5381c5c6daa97585cbc284b Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Thu, 9 Oct 2014 23:13:54 +0800 Subject: [PATCH 14/30] fix split type --- .../gnucash/android/db/DatabaseHelper.java | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/app/src/org/gnucash/android/db/DatabaseHelper.java b/app/src/org/gnucash/android/db/DatabaseHelper.java index c9c6c00a7..f6107f1fd 100644 --- a/app/src/org/gnucash/android/db/DatabaseHelper.java +++ b/app/src/org/gnucash/android/db/DatabaseHelper.java @@ -285,26 +285,26 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + SplitEntry.COLUMN_AMOUNT + " , " + SplitEntry.COLUMN_ACCOUNT_UID + " , " + SplitEntry.COLUMN_TRANSACTION_UID + " ) SELECT " - // _ID, autogenerated + "LOWER(HEX(RANDOMBLOB(16))) , " - // COLUMN_MEMO, empty - + "CASE WHEN " + TransactionEntry.TABLE_NAME + "_bak.type IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " - + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END ELSE CASE WHEN " - + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END END , " + + "CASE WHEN " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_TYPE + " IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END ELSE CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END END , " + "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , " + TransactionEntry.TABLE_NAME + "_bak.account_uid , " + TransactionEntry.TABLE_NAME + "_bak." + TransactionEntry.COLUMN_UID - + " FROM " + TransactionEntry.TABLE_NAME + "_bak UNION SELECT " - // _ID, autogenerated + + " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME + + " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID + + " UNION SELECT " + "LOWER(HEX(RANDOMBLOB(16))) AS " + SplitEntry.COLUMN_UID + " , " - // COLUMN_MEMO, empty - + "CASE WHEN " + TransactionEntry.TABLE_NAME + "_bak.type IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " - + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END ELSE CASE WHEN " - + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END END , " + + "CASE WHEN " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_TYPE + " IN ( 'CASH' , 'BANK', 'ASSET', 'EXPENSE', 'RECEIVABLE', 'STOCK', 'MUTUAL' ) THEN CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'DEBIT' ELSE 'CREDIT' END ELSE CASE WHEN " + + SplitEntry.COLUMN_AMOUNT + " < 0 THEN 'CREDIT' ELSE 'DEBIT' END END , " + "ABS ( " + TransactionEntry.TABLE_NAME + "_bak.amount ) , " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " , " + TransactionEntry.TABLE_NAME + "_baK." + TransactionEntry.COLUMN_UID - + " FROM " + TransactionEntry.TABLE_NAME + "_bak WHERE " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " IS NOT NULL" + + " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME + + " ON " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID + + " WHERE " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " IS NOT NULL" ); // drop backup transaction table db.execSQL("DROP TABLE " + TransactionEntry.TABLE_NAME + "_bak"); From 3f2a1d1b0a04ec9d6afea332834dee53fe868b6e Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Fri, 10 Oct 2014 00:03:58 +0800 Subject: [PATCH 15/30] fix split type --- app/src/org/gnucash/android/db/DatabaseHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/db/DatabaseHelper.java b/app/src/org/gnucash/android/db/DatabaseHelper.java index f6107f1fd..90ebb7f41 100644 --- a/app/src/org/gnucash/android/db/DatabaseHelper.java +++ b/app/src/org/gnucash/android/db/DatabaseHelper.java @@ -303,7 +303,7 @@ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " , " + TransactionEntry.TABLE_NAME + "_baK." + TransactionEntry.COLUMN_UID + " FROM " + TransactionEntry.TABLE_NAME + "_bak , " + AccountEntry.TABLE_NAME - + " ON " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID + + " ON " + TransactionEntry.TABLE_NAME + "_bak.account_uid = " + AccountEntry.TABLE_NAME + "." + AccountEntry.COLUMN_UID + " WHERE " + TransactionEntry.TABLE_NAME + "_bak." + KEY_DOUBLE_ENTRY_ACCOUNT_UID + " IS NOT NULL" ); // drop backup transaction table From 032b9b79d7ca66a3d5f4141ebf744b378c05705c Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Fri, 10 Oct 2014 21:25:15 +0800 Subject: [PATCH 16/30] delete all splits of a transaction --- app/src/org/gnucash/android/db/AccountsDbAdapter.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/org/gnucash/android/db/AccountsDbAdapter.java index 3ce9583d9..a93a9f57a 100644 --- a/app/src/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/org/gnucash/android/db/AccountsDbAdapter.java @@ -281,7 +281,11 @@ public boolean destructiveDeleteAccount(long rowId){ } //delete splits in this account mDb.delete(SplitEntry.TABLE_NAME, - SplitEntry.COLUMN_ACCOUNT_UID + "=?", + SplitEntry.COLUMN_TRANSACTION_UID + " IN ( SELECT DISTINCT " + + TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID + + " FROM trans_split_acct WHERE " + + AccountEntry.TABLE_NAME + "_" + AccountEntry.COLUMN_UID + + " = ? )", new String[]{getAccountUID(rowId)}); deleteRecord(AccountEntry.TABLE_NAME, rowId); mDb.setTransactionSuccessful(); From db4c848519b42830699bfdf070e3c1205f896274 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Sat, 11 Oct 2014 08:30:29 +0800 Subject: [PATCH 17/30] delete empty transactions --- app/src/org/gnucash/android/db/AccountsDbAdapter.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/src/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/org/gnucash/android/db/AccountsDbAdapter.java index a93a9f57a..4d1d90437 100644 --- a/app/src/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/org/gnucash/android/db/AccountsDbAdapter.java @@ -279,6 +279,9 @@ public boolean destructiveDeleteAccount(long rowId){ } } } + // TODO: with "ON DELETE CASCADE", the first two delete will not be necessary. + // deleteRecord(AccountEntry.TABLE_NAME, rowId); will delete related + // transactions and splits //delete splits in this account mDb.delete(SplitEntry.TABLE_NAME, SplitEntry.COLUMN_TRANSACTION_UID + " IN ( SELECT DISTINCT " @@ -287,6 +290,14 @@ public boolean destructiveDeleteAccount(long rowId){ + AccountEntry.TABLE_NAME + "_" + AccountEntry.COLUMN_UID + " = ? )", new String[]{getAccountUID(rowId)}); + // delete empty transactions + // trans_split_acct is an inner joint, empty transactions will + // not be selected in this view + mDb.delete(TransactionEntry.TABLE_NAME, + TransactionEntry.COLUMN_UID + " NOT IN ( SELECT DISTINCT " + + TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID + + " FROM trans_split_acct", + null); deleteRecord(AccountEntry.TABLE_NAME, rowId); mDb.setTransactionSuccessful(); return true; From dc5a365ef654933696b2054c8cb3187a4943e544 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Sat, 11 Oct 2014 21:07:30 +0800 Subject: [PATCH 18/30] delete all splits and transaction --- .../gnucash/android/db/AccountsDbAdapter.java | 2 +- .../gnucash/android/db/SplitsDbAdapter.java | 18 ++++++++++++------ .../android/db/TransactionsDbAdapter.java | 3 +-- .../transaction/TransactionsListFragment.java | 4 +--- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/app/src/org/gnucash/android/db/AccountsDbAdapter.java b/app/src/org/gnucash/android/db/AccountsDbAdapter.java index 4d1d90437..98a79da04 100644 --- a/app/src/org/gnucash/android/db/AccountsDbAdapter.java +++ b/app/src/org/gnucash/android/db/AccountsDbAdapter.java @@ -296,7 +296,7 @@ public boolean destructiveDeleteAccount(long rowId){ mDb.delete(TransactionEntry.TABLE_NAME, TransactionEntry.COLUMN_UID + " NOT IN ( SELECT DISTINCT " + TransactionEntry.TABLE_NAME + "_" + TransactionEntry.COLUMN_UID - + " FROM trans_split_acct", + + " FROM trans_split_acct )", null); deleteRecord(AccountEntry.TABLE_NAME, rowId); mDb.setTransactionSuccessful(); diff --git a/app/src/org/gnucash/android/db/SplitsDbAdapter.java b/app/src/org/gnucash/android/db/SplitsDbAdapter.java index e01a93fbf..aa333f0d8 100644 --- a/app/src/org/gnucash/android/db/SplitsDbAdapter.java +++ b/app/src/org/gnucash/android/db/SplitsDbAdapter.java @@ -515,13 +515,19 @@ public long getTransactionID(String transactionUID){ * @param transactionId Database record ID of the transaction * @return true if at least one split was deleted, false otherwise. */ - public boolean deleteSplitsForTransaction(long transactionId){ + public boolean deleteSplitsForTransaction(long transactionId) { String trxUID = getTransactionUID(transactionId); - boolean result = mDb.delete(SplitEntry.TABLE_NAME, - SplitEntry.COLUMN_TRANSACTION_UID + "=?", - new String[]{trxUID}) > 0; - result &= deleteTransaction(transactionId); - return result; + mDb.beginTransaction(); + try { + mDb.delete(SplitEntry.TABLE_NAME, + SplitEntry.COLUMN_TRANSACTION_UID + "=?", + new String[]{trxUID}); + boolean result = deleteTransaction(transactionId); + mDb.setTransactionSuccessful(); + return result; + } finally { + mDb.endTransaction(); + } } /** diff --git a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java index 69675d118..abfc0eb60 100644 --- a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java +++ b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java @@ -439,8 +439,7 @@ public String getUID(long transactionId){ @Override public boolean deleteRecord(long rowId){ Log.d(TAG, "Delete transaction with record Id: " + rowId); - return mSplitsDbAdapter.deleteSplitsForTransaction(rowId) && - deleteRecord(TransactionEntry.TABLE_NAME, rowId); + return mSplitsDbAdapter.deleteSplitsForTransaction(rowId); } /** diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionsListFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionsListFragment.java index 337262b80..3b0620efe 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionsListFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionsListFragment.java @@ -117,11 +117,9 @@ public boolean onActionItemClicked(ActionMode mode, MenuItem item) { return true; case R.id.context_menu_delete: - SplitsDbAdapter splitsDbAdapter = new SplitsDbAdapter(getActivity()); for (long id : getListView().getCheckedItemIds()) { - splitsDbAdapter.deleteSplitsForTransactionAndAccount(mTransactionsDbAdapter.getUID(id), mAccountUID); + mTransactionsDbAdapter.deleteRecord(id); } - splitsDbAdapter.close(); refresh(); mode.finish(); WidgetConfigurationActivity.updateAllWidgets(getActivity()); From 40d759d595cd33d11dd8d6eca1bc447ec1290b60 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Sat, 11 Oct 2014 22:08:58 +0800 Subject: [PATCH 19/30] FIX: add split will throw NPE --- .../ui/transaction/dialog/SplitEditorDialogFragment.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java index a150ca79c..52ac40ed0 100644 --- a/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/dialog/SplitEditorDialogFragment.java @@ -229,7 +229,8 @@ public void onClick(View view) { updateTransferAccountsList(accountsSpinner); accountsSpinner.setOnItemSelectedListener(new TypeButtonLabelUpdater(splitTypeButton)); - Currency accountCurrency = Currency.getInstance(mAccountsDbAdapter.getCurrencyCode(split.getAccountUID())); + Currency accountCurrency = Currency.getInstance(mAccountsDbAdapter.getCurrencyCode( + split == null ? mAccountUID : split.getAccountUID())); splitCurrencyTextView.setText(accountCurrency.getSymbol()); splitTypeButton.setAmountFormattingListener(splitAmountEditText, splitCurrencyTextView); splitTypeButton.setChecked(mBaseAmount.signum() > 0); From cb860bc3cbb4eb96a44552bf18b8fcccea035345 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Sun, 12 Oct 2014 12:14:53 +0800 Subject: [PATCH 20/30] Set Transaction UID when set splitList --- app/src/org/gnucash/android/model/Transaction.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/org/gnucash/android/model/Transaction.java b/app/src/org/gnucash/android/model/Transaction.java index 8e1cddc30..e993c9554 100644 --- a/app/src/org/gnucash/android/model/Transaction.java +++ b/app/src/org/gnucash/android/model/Transaction.java @@ -186,6 +186,9 @@ public List getSplits(String accountUID){ */ public void setSplits(List splitList){ mSplitList = splitList; + for (Split split : splitList) { + split.setTransactionUID(mUID); + } } /** From beaf5875fe4f48cb8d292409249e2459fa231f47 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 15 Oct 2014 20:36:28 +0800 Subject: [PATCH 21/30] delete splits when transaction is saved. --- .../android/db/TransactionsDbAdapter.java | 34 ++++++++++++++++--- .../transaction/TransactionFormFragment.java | 16 ++++++--- 2 files changed, 41 insertions(+), 9 deletions(-) diff --git a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java index abfc0eb60..be24ba899 100644 --- a/app/src/org/gnucash/android/db/TransactionsDbAdapter.java +++ b/app/src/org/gnucash/android/db/TransactionsDbAdapter.java @@ -22,9 +22,11 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; +import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteQueryBuilder; import android.database.sqlite.SQLiteStatement; +import android.text.TextUtils; import android.util.Log; import org.gnucash.android.model.*; @@ -86,16 +88,40 @@ public long addTransaction(Transaction transaction){ contentValues.put(TransactionEntry.COLUMN_RECURRENCE_PERIOD, transaction.getRecurrencePeriod()); Log.d(TAG, "Replacing transaction in db"); - long rowId = mDb.replace(TransactionEntry.TABLE_NAME, null, contentValues); + long rowId = -1; + mDb.beginTransaction(); + try { + rowId = mDb.replaceOrThrow(TransactionEntry.TABLE_NAME, null, contentValues); - if (rowId > 0){ Log.d(TAG, "Adding splits for transaction"); + ArrayList splitUIDs = new ArrayList(transaction.getSplits().size()); for (Split split : transaction.getSplits()) { - mSplitsDbAdapter.addSplit(split); + contentValues.clear(); + contentValues.put(SplitEntry.COLUMN_UID, split.getUID()); + contentValues.put(SplitEntry.COLUMN_AMOUNT, split.getAmount().absolute().toPlainString()); + contentValues.put(SplitEntry.COLUMN_TYPE, split.getType().name()); + contentValues.put(SplitEntry.COLUMN_MEMO, split.getMemo()); + contentValues.put(SplitEntry.COLUMN_ACCOUNT_UID, split.getAccountUID()); + contentValues.put(SplitEntry.COLUMN_TRANSACTION_UID, split.getTransactionUID()); + splitUIDs.add(split.getUID()); + + Log.d(TAG, "Replace transaction split in db"); + mDb.replaceOrThrow(SplitEntry.TABLE_NAME, null, contentValues); } Log.d(TAG, transaction.getSplits().size() + " splits added"); + + long deleted = mDb.delete(SplitEntry.TABLE_NAME, + SplitEntry.COLUMN_TRANSACTION_UID + " = ? AND " + + SplitEntry.COLUMN_UID + " NOT IN ('" + TextUtils.join("' , '", splitUIDs) + "')", + new String[]{transaction.getUID()}); + Log.d(TAG, deleted + " splits deleted"); + mDb.setTransactionSuccessful(); + } catch (SQLException sqle) { + sqle.printStackTrace(); + } finally { + mDb.endTransaction(); } - return rowId; + return rowId; } /** diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index abb5d813b..723bd9899 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -182,6 +182,11 @@ public class TransactionFormFragment extends SherlockFragment implements private String mAccountUID; private List mSplitsList = new ArrayList(); + /** + * list to hold deleted splits. This split should only be deleted from + * DB when the transaction is saved. + */ + private List mDeletedSplitUIDList = new ArrayList(); /** * Create the view and retrieve references to the UI elements @@ -671,6 +676,8 @@ private void saveNewTransaction() { mTransaction.setTime(cal.getTimeInMillis()); mTransaction.setNote(notes); + // set as not exported. + mTransaction.setExported(false); //save the normal transaction first mTransactionsDbAdapter.addTransaction(mTransaction); scheduleRecurringTransaction(); @@ -761,11 +768,10 @@ public void setSplitList(List splitList, List removedSplitUIDs){ setAmountEditViewVisible(View.GONE); } - SplitsDbAdapter splitsDbAdapter = new SplitsDbAdapter(getActivity()); - for (String removedSplitUID : removedSplitUIDs) { - splitsDbAdapter.deleteRecord(splitsDbAdapter.getID(removedSplitUID)); - } - splitsDbAdapter.close(); + // save the deleted UID list. Use add instead of assign in case this + // is called multiple times + // The splits will be actually deleted when the transaction is saved. + mDeletedSplitUIDList.addAll(removedSplitUIDs); } /** From 163be8d7d4bd5e74dcc37645a71673abaa4469a6 Mon Sep 17 00:00:00 2001 From: Yongxin Wang Date: Wed, 15 Oct 2014 20:45:05 +0800 Subject: [PATCH 22/30] remove unused local variable --- .../ui/transaction/TransactionFormFragment.java | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java index 723bd9899..5fde6aa0f 100644 --- a/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java +++ b/app/src/org/gnucash/android/ui/transaction/TransactionFormFragment.java @@ -182,11 +182,6 @@ public class TransactionFormFragment extends SherlockFragment implements private String mAccountUID; private List mSplitsList = new ArrayList(); - /** - * list to hold deleted splits. This split should only be deleted from - * DB when the transaction is saved. - */ - private List mDeletedSplitUIDList = new ArrayList(); /** * Create the view and retrieve references to the UI elements @@ -767,11 +762,6 @@ public void setSplitList(List splitList, List removedSplitUIDs){ mAmountEditText.setEnabled(false); setAmountEditViewVisible(View.GONE); } - - // save the deleted UID list. Use add instead of assign in case this - // is called multiple times - // The splits will be actually deleted when the transaction is saved. - mDeletedSplitUIDList.addAll(removedSplitUIDs); } /** From f4f2a818bd18b23fbe545688b2aaf7af8fa8265f Mon Sep 17 00:00:00 2001 From: Oleksandr Tyshkovets Date: Sat, 15 Nov 2014 19:23:14 +0300 Subject: [PATCH 23/30] Redesigned passcode lock screen --- app/res/layout/fragment_numeric_keyboard.xml | 417 ++++++++++--------- 1 file changed, 215 insertions(+), 202 deletions(-) diff --git a/app/res/layout/fragment_numeric_keyboard.xml b/app/res/layout/fragment_numeric_keyboard.xml index e4a007df8..bff9f93a7 100644 --- a/app/res/layout/fragment_numeric_keyboard.xml +++ b/app/res/layout/fragment_numeric_keyboard.xml @@ -16,216 +16,229 @@ limitations under the License. --> - - - - -