File indexing completed on 2024-05-19 05:08:21

0001 /*
0002     SPDX-FileCopyrightText: 2019 Thomas Baumgart <tbaumgart@kde.org>
0003     SPDX-License-Identifier: GPL-2.0-or-later
0004 */
0005 
0006 
0007 #include "ledgerpayeefilter.h"
0008 #include "ledgerfilterbase_p.h"
0009 
0010 // ----------------------------------------------------------------------------
0011 // QT Includes
0012 
0013 // ----------------------------------------------------------------------------
0014 // KDE Includes
0015 
0016 // ----------------------------------------------------------------------------
0017 // Project Includes
0018 
0019 #include "mymoneyenums.h"
0020 #include "mymoneymoney.h"
0021 #include "mymoneyaccount.h"
0022 #include "mymoneyfile.h"
0023 #include "journalmodel.h"
0024 #include "accountsmodel.h"
0025 
0026 class LedgerPayeeFilterPrivate : public LedgerFilterBasePrivate
0027 {
0028 public:
0029     explicit LedgerPayeeFilterPrivate(LedgerPayeeFilter* qq)
0030         : LedgerFilterBasePrivate(qq)
0031         , balanceCalculationPending(false)
0032     {}
0033 
0034     ~LedgerPayeeFilterPrivate()
0035     {
0036     }
0037 
0038     bool                        balanceCalculationPending;
0039 };
0040 
0041 
0042 LedgerPayeeFilter::LedgerPayeeFilter(QObject* parent, QVector<QAbstractItemModel*> specialJournalModels)
0043     : LedgerFilterBase(new LedgerPayeeFilterPrivate(this), parent)
0044 {
0045     Q_D(LedgerPayeeFilter);
0046 
0047     setFilterRole(eMyMoney::Model::SplitPayeeIdRole);
0048     setObjectName("LedgerPayeeFilter");
0049     setFilterKeyColumn(0);
0050 
0051     d->concatModel->setObjectName("LedgerView concatModel");
0052     d->concatModel->addSourceModel(MyMoneyFile::instance()->journalModel());
0053 
0054     for (const auto model : specialJournalModels) {
0055         d->concatModel->addSourceModel(model);
0056     }
0057 
0058     setSourceModel(d->concatModel);
0059 }
0060 
0061 LedgerPayeeFilter::~LedgerPayeeFilter()
0062 {
0063 }
0064 
0065 void LedgerPayeeFilter::setShowBalanceInverted(bool inverted)
0066 {
0067     Q_D(LedgerPayeeFilter);
0068     d->showValuesInverted = inverted;
0069 }
0070 
0071 void LedgerPayeeFilter::recalculateBalancesOnIdle(const QString& accountId)
0072 {
0073     Q_UNUSED(accountId);
0074     Q_D(LedgerPayeeFilter);
0075 
0076     // make sure the balances are recalculated but trigger only once
0077     if(!d->balanceCalculationPending) {
0078         d->balanceCalculationPending = true;
0079         QMetaObject::invokeMethod(this, "recalculateBalances", Qt::QueuedConnection);
0080     }
0081 }
0082 
0083 void LedgerPayeeFilter::recalculateBalances()
0084 {
0085     Q_D(LedgerPayeeFilter);
0086 
0087     if (sourceModel() == nullptr || d->filterIds.isEmpty())
0088         return;
0089 
0090     /// @todo port to new model code
0091 #if 0
0092     const auto start = index(0, 0);
0093     const auto indexes = match(start, eMyMoney::Model::SplitAccountIdRole, d->payeeId, -1);
0094     MyMoneyMoney balance;
0095     for(const auto &idx : indexes) {
0096         if(d->showValuesInverted) {
0097             balance -= idx.data(eMyMoney::Model::SplitSharesRole).value<MyMoneyMoney>();
0098         } else {
0099             balance += idx.data(eMyMoney::Model::SplitSharesRole).value<MyMoneyMoney>();
0100         }
0101         const auto dispIndex = index(idx.row(), JournalModel::Column::Balance);
0102         setData(dispIndex, QVariant::fromValue(balance), Qt::DisplayRole);
0103     }
0104 #endif
0105 
0106     // filterModel->invalidate();
0107     const QModelIndex top = index(0, JournalModel::Column::Balance);
0108     const QModelIndex bottom = index(rowCount()-1, JournalModel::Column::Balance);
0109 
0110     Q_EMIT dataChanged(top, bottom);
0111     d->balanceCalculationPending = false;
0112 }
0113 
0114 void LedgerPayeeFilter::setPayeeIdList(const QStringList& payeeIds)
0115 {
0116     Q_D(LedgerPayeeFilter);
0117 
0118     setFilterFixedStrings(payeeIds);
0119 
0120     /// @todo sorting - move to new sort definition
0121     setSortRole(eMyMoney::Model::TransactionPostDateRole);
0122     sort(JournalModel::Column::Date, sortOrder());
0123 
0124     invalidate();
0125 
0126     // if balance calculation has not been triggered, then run it immediately
0127     if(!d->balanceCalculationPending) {
0128         recalculateBalances();
0129     }
0130 }
0131 
0132 bool LedgerPayeeFilter::filterAcceptsRow(int source_row, const QModelIndex& source_parent) const
0133 {
0134     Q_D(const LedgerPayeeFilter);
0135 
0136     bool rc = LedgerFilterBase::filterAcceptsRow(source_row,  source_parent);
0137 
0138     if (rc) {
0139         QModelIndex idx = sourceModel()->index(source_row, 0, source_parent);
0140 
0141         // special dates are shown when sorted by date
0142         if (d->isSpecialDatesModel(idx)) {
0143             return (sortRole() == eMyMoney::Model::TransactionPostDateRole);
0144         }
0145 
0146         // only display splits that reference an asset or liability account
0147         const auto accountId = idx.data(eMyMoney::Model::SplitAccountIdRole).toString();
0148         idx = MyMoneyFile::instance()->accountsModel()->indexById(accountId);
0149         const auto accountGroup = static_cast<eMyMoney::Account::Type>(idx.data(eMyMoney::Model::AccountGroupRole).toInt());
0150         switch(accountGroup) {
0151         case eMyMoney::Account::Type::Asset:
0152         case eMyMoney::Account::Type::Liability:
0153             break;
0154         default:
0155             return false;
0156         }
0157     }
0158     return rc;
0159 }