From 2f824368d15bee5c92084e2294068c7401e5e93f Mon Sep 17 00:00:00 2001 From: JeanGarf Date: Fri, 6 Mar 2020 20:49:32 +0100 Subject: [PATCH] #876 - Correct balance amount computation and factorize into getAmountColor() --- .../gnucash/android/model/AccountType.java | 58 ++++++++++ .../java/org/gnucash/android/model/Split.java | 90 +++++++++------ .../ui/report/ReportsOverviewFragment.java | 7 +- .../TransactionDetailActivity.java | 103 +++++++++++++----- .../ui/util/widget/TransactionTypeSwitch.java | 26 +---- 5 files changed, 202 insertions(+), 82 deletions(-) diff --git a/app/src/main/java/org/gnucash/android/model/AccountType.java b/app/src/main/java/org/gnucash/android/model/AccountType.java index a0837f477..9b856ef90 100644 --- a/app/src/main/java/org/gnucash/android/model/AccountType.java +++ b/app/src/main/java/org/gnucash/android/model/AccountType.java @@ -1,5 +1,11 @@ package org.gnucash.android.model; +import android.support.annotation.ColorInt; +import android.support.annotation.ColorRes; + +import org.gnucash.android.R; +import org.gnucash.android.app.GnuCashApplication; + /** * The type of account * This are the different types specified by the OFX format and @@ -37,6 +43,48 @@ public enum AccountType { //nothing to see here, move along } + // TODO TW C 2020-03-06 : Enlever le static + + /** + * Compute red/green color according to accountType and isCredit + * + * @param isCredit + * @param accountType + * + * @return + */ + @ColorInt + public static int getAmountColor(final boolean isCredit, + final AccountType accountType) { + + AccountType tmpAccountType = ((accountType != null) + ? accountType + : AccountType.ASSET); + + @ColorRes final int colorRes; + + // TODO TW C 2020-03-06 : Trouver un meilleur nom + final boolean specialAccountType = tmpAccountType.isEquityAccount() || tmpAccountType.isResultAccount(); + + if ((!specialAccountType && isCredit) || (specialAccountType && !isCredit)) { + // TODO TW C 2020-03-02 : commenter + // CREDIT + + // RED + colorRes = R.color.debit_red; + + } else { + // DEBIT + + // GREEN + colorRes = R.color.credit_green; + } + + return GnuCashApplication.getAppContext() + .getResources() + .getColor(colorRes); + } + public boolean hasDebitNormalBalance() { return mNormalBalance == TransactionType.DEBIT; @@ -51,6 +99,16 @@ public TransactionType getNormalBalanceType() { return mNormalBalance; } + public boolean isAssetAccount() { + + return ASSET.equals(this) || BANK.equals(this) || CASH.equals(this); + } + + public boolean isEquityAccount() { + + return EQUITY.equals(this); + } + // TODO TW C 2020-03-03 : A renommer en anglais public boolean isResultAccount() { diff --git a/app/src/main/java/org/gnucash/android/model/Split.java b/app/src/main/java/org/gnucash/android/model/Split.java index c659cd1e4..261b10a40 100644 --- a/app/src/main/java/org/gnucash/android/model/Split.java +++ b/app/src/main/java/org/gnucash/android/model/Split.java @@ -301,37 +301,6 @@ public Money getFormattedQuantity(){ return getFormattedAmount(mQuantity, mAccountUID, mSplitType); } - /** - * Splits are saved as absolute values to the database, with no negative numbers. - * The type of movement the split causes to the balance of an account determines - * its sign, and that depends on the split type and the account type - * @param amount Money amount to format - * @param accountUID GUID of the account - * @param splitType Transaction type of the split - * @return -{@code amount} if the amount would reduce the balance of - * {@code account}, otherwise +{@code amount} - */ - private static Money getFormattedAmount(Money amount, String accountUID, TransactionType - splitType){ - boolean isDebitAccount = AccountsDbAdapter.getInstance().getAccountType(accountUID).hasDebitNormalBalance(); - Money absAmount = amount.abs(); - - boolean isDebitSplit = splitType == TransactionType.DEBIT; - if (isDebitAccount) { - if (isDebitSplit) { - return absAmount; - } else { - return absAmount.negate(); - } - } else { - if (isDebitSplit) { - return absAmount.negate(); - } else { - return absAmount; - } - } - } - /** * Return the reconciled state of this split *

@@ -351,6 +320,54 @@ public char getReconcileState() { return mReconcileState; } + /** + * Splits are saved as absolute values to the database, with no negative numbers. + * The type of movement the split causes to the balance of an account determines + * its sign, and that depends on the split type and the account type + * @param amount Money amount to format + * @param accountUID GUID of the account + * @param splitType Transaction type of the split + * @return -{@code amount} if the amount would reduce the balance of + * {@code account}, otherwise +{@code amount} + */ + private static Money getFormattedAmount(Money amount, + String accountUID, + TransactionType splitType) { + +// boolean isDebitAccount = AccountsDbAdapter.getInstance() +// .getAccountType(accountUID) +// .hasDebitNormalBalance(); + + Money absAmount = amount.abs(); + + boolean isDebitSplit = splitType == TransactionType.DEBIT; + +// if (isDebitAccount) { +// if (isDebitSplit) { +// return absAmount; +// } else { +// return absAmount.negate(); +// } +// } else { +// if (isDebitSplit) { +// return absAmount.negate(); +// } else { +// return absAmount; +// } +// } + + if (isDebitSplit) { + // It is a Debit Split + + return absAmount; + + } else { + // It is not a Debit Split + + return absAmount.negate(); + } + } + /** * Check if this split is reconciled * @return {@code true} if the split is reconciled, {@code false} otherwise @@ -394,7 +411,16 @@ public void setReconcileDate(Timestamp reconcileDate) { @Override public String toString() { - return mSplitType.name() + " of " + mValue.toString() + " in account: " + mAccountUID; + + return mSplitType.name() + + " of " + + mValue.toString() + + " in account: " + + mAccountUID + + " (" + + AccountsDbAdapter.getInstance() + .getAccountFullName(mAccountUID) + + ")"; } /** diff --git a/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java b/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java index 9b81fc5b6..6d99db6fd 100644 --- a/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java +++ b/app/src/main/java/org/gnucash/android/ui/report/ReportsOverviewFragment.java @@ -213,9 +213,10 @@ protected void displayReport() { mChart.highlightValues(null); mChart.invalidate(); - TransactionsActivity.displayBalance(mTotalAssets, mAssetsBalance); - TransactionsActivity.displayBalance(mTotalLiabilities, mLiabilitiesBalance); - TransactionsActivity.displayBalance(mNetWorth, mAssetsBalance.subtract(mLiabilitiesBalance)); + TransactionsActivity.displayBalance(mTotalAssets, mAssetsBalance, AccountType.ASSET); + TransactionsActivity.displayBalance(mTotalLiabilities, mLiabilitiesBalance, AccountType.LIABILITY); + // #8xx + TransactionsActivity.displayBalance(mNetWorth, mAssetsBalance.add(mLiabilitiesBalance), null); } /** diff --git a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java index 44771f872..eb22e5352 100644 --- a/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java +++ b/app/src/main/java/org/gnucash/android/ui/transaction/TransactionDetailActivity.java @@ -22,9 +22,11 @@ import org.gnucash.android.model.ScheduledAction; import org.gnucash.android.model.Split; import org.gnucash.android.model.Transaction; +import org.gnucash.android.model.TransactionType; import org.gnucash.android.ui.common.FormActivity; import org.gnucash.android.ui.common.UxArgument; import org.gnucash.android.ui.passcode.PasscodeLockActivity; +import org.gnucash.android.ui.util.AccountUtils; import java.text.DateFormat; import java.util.Date; @@ -40,14 +42,55 @@ */ public class TransactionDetailActivity extends PasscodeLockActivity { - @BindView(R.id.trn_description) TextView mTransactionDescription; - @BindView(R.id.trn_time_and_date) TextView mTimeAndDate; - @BindView(R.id.trn_recurrence) TextView mRecurrence; - @BindView(R.id.trn_notes) TextView mNotes; + class SplitAmountViewHolder { + @BindView(R.id.split_account_name) TextView accountName; + @BindView(R.id.split_debit) TextView splitDebitView; + @BindView(R.id.split_credit) TextView splitCreditView; + + View itemView; + + public SplitAmountViewHolder(View view, + Split split) { + + itemView = view; + + ButterKnife.bind(this, + view); + + AccountsDbAdapter accountsDbAdapter = AccountsDbAdapter.getInstance(); + + final String accountUID = split.getAccountUID(); + + accountName.setText(accountsDbAdapter.getAccountFullName(accountUID)); + + // quantity (positive or negative number) + Money quantity = split.getFormattedQuantity(); + + // Define debit or credit view + // #8xx +// TextView balanceView = quantity.isNegative() +// ? splitDebitView +// : splitCreditView; + TextView balanceView = TransactionType.CREDIT.equals(split.getType()) + ? splitCreditView + : splitDebitView; + + TransactionsActivity.displayBalance(balanceView, + quantity, + AccountsDbAdapter.getInstance() + .getAccountType(split.getAccountUID())); + } + + } // Class SplitAmountViewHolder + @BindView(R.id.toolbar) Toolbar mToolBar; + @BindView(R.id.trn_description) TextView mTransactionDescription; @BindView(R.id.transaction_account) TextView mTransactionAccount; @BindView(R.id.balance_debit) TextView mDebitBalance; @BindView(R.id.balance_credit) TextView mCreditBalance; + @BindView(R.id.trn_time_and_date) TextView mTimeAndDate; + @BindView(R.id.trn_recurrence) TextView mRecurrence; + @BindView(R.id.trn_notes) TextView mNotes; @BindView(R.id.fragment_transaction_details) TableLayout mDetailTableLayout; @@ -92,25 +135,6 @@ protected void onCreate(Bundle savedInstanceState) { } - class SplitAmountViewHolder { - @BindView(R.id.split_account_name) TextView accountName; - @BindView(R.id.split_debit) TextView splitDebit; - @BindView(R.id.split_credit) TextView splitCredit; - - View itemView; - - public SplitAmountViewHolder(View view, Split split){ - itemView = view; - ButterKnife.bind(this, view); - - AccountsDbAdapter accountsDbAdapter = AccountsDbAdapter.getInstance(); - accountName.setText(accountsDbAdapter.getAccountFullName(split.getAccountUID())); - Money quantity = split.getFormattedQuantity(); - TextView balanceView = quantity.isNegative() ? splitDebit : splitCredit; - TransactionsActivity.displayBalance(balanceView, quantity); - } - } - /** * Reads the transaction information from the database and binds it to the views */ @@ -118,35 +142,64 @@ private void bindViews(){ TransactionsDbAdapter transactionsDbAdapter = TransactionsDbAdapter.getInstance(); Transaction transaction = transactionsDbAdapter.getRecord(mTransactionUID); + // Transaction description mTransactionDescription.setText(transaction.getDescription()); + + // Account Full Name mTransactionAccount.setText(getString(R.string.label_inside_account_with_name, AccountsDbAdapter.getInstance().getAccountFullName(mAccountUID))); + // + // Account balance + // + AccountsDbAdapter accountsDbAdapter = AccountsDbAdapter.getInstance(); + // Compute balance at Transaction time Money accountBalance = accountsDbAdapter.getAccountBalance(mAccountUID, -1, transaction.getTimeMillis()); - TextView balanceTextView = accountBalance.isNegative() ? mDebitBalance : mCreditBalance; - TransactionsActivity.displayBalance(balanceTextView, accountBalance); + + // #8xx + // Define in which field (Debit or Credit) the balance shall be displayed + TextView balanceTextView = accountBalance.isNegative() ? mCreditBalance : mDebitBalance ; + + TransactionsActivity.displayBalance(balanceTextView, + accountBalance, + accountsDbAdapter.getAccountType(mAccountUID)); + + // + // Détails + // mDetailTableRows = mDetailTableLayout.getChildCount(); + boolean useDoubleEntry = GnuCashApplication.isDoubleEntryEnabled(); LayoutInflater inflater = LayoutInflater.from(this); int index = 0; + for (Split split : transaction.getSplits()) { + if (!useDoubleEntry && split.getAccountUID().equals( accountsDbAdapter.getImbalanceAccountUID(split.getValue().getCommodity()))) { //do now show imbalance accounts for single entry use case continue; } + View view = inflater.inflate(R.layout.item_split_amount_info, mDetailTableLayout, false); SplitAmountViewHolder viewHolder = new SplitAmountViewHolder(view, split); mDetailTableLayout.addView(viewHolder.itemView, index++); } + // + // Date + // Date trnDate = new Date(transaction.getTimeMillis()); String timeAndDate = DateFormat.getDateInstance(DateFormat.FULL).format(trnDate); mTimeAndDate.setText(timeAndDate); + // + // + // + if (transaction.getScheduledActionUID() != null){ ScheduledAction scheduledAction = ScheduledActionDbAdapter.getInstance().getRecord(transaction.getScheduledActionUID()); mRecurrence.setText(scheduledAction.getRepeatString()); diff --git a/app/src/main/java/org/gnucash/android/ui/util/widget/TransactionTypeSwitch.java b/app/src/main/java/org/gnucash/android/ui/util/widget/TransactionTypeSwitch.java index 8b83c3cac..66f249c71 100644 --- a/app/src/main/java/org/gnucash/android/ui/util/widget/TransactionTypeSwitch.java +++ b/app/src/main/java/org/gnucash/android/ui/util/widget/TransactionTypeSwitch.java @@ -17,7 +17,7 @@ package org.gnucash.android.ui.util.widget; import android.content.Context; -import android.support.v4.content.ContextCompat; +import android.support.annotation.ColorInt; import android.support.v7.widget.SwitchCompat; import android.util.AttributeSet; import android.widget.CompoundButton; @@ -234,29 +234,11 @@ private void setSwitchTextAndColor(final boolean isCredit) { ); // - // Set text color + // Set text color of views // - // TODO TW C 2020-03-02 : A renommer et commenter - if ((mAccountType.isResultAccount() && !isCredit) || (!mAccountType.isResultAccount() && isCredit)) { - // CREDIT - - // RED - int red = ContextCompat.getColor(getContext(), - R.color.debit_red); - setAllTextsColor(red); - - } else { - // DEBIT - - // GREEN - int green = ContextCompat.getColor(getContext(), - R.color.credit_green); - setAllTextsColor(green); - } - } - - private void setAllTextsColor(final int color) { + @ColorInt final int color = AccountType.getAmountColor(isCredit, + getAccountType()); TransactionTypeSwitch.this.setTextColor(color); mAmountEditText.setTextColor(color);