File indexing completed on 2024-05-12 16:42:39

0001 /*
0002     SPDX-FileCopyrightText: 2004-2006 Ace Jones <acejones@users.sourceforge.net>
0003     SPDX-FileCopyrightText: 2006 Darren Gould <darren_gould@gmx.de>
0004     SPDX-FileCopyrightText: 2007-2010 Alvaro Soliverez <asoliverez@gmail.com>
0005     SPDX-FileCopyrightText: 2017-2018 Łukasz Wojniłowicz <lukasz.wojnilowicz@gmail.com>
0006     SPDX-FileCopyrightText: 2018 Michael Kiefer <Michael-Kiefer@web.de>
0007     SPDX-License-Identifier: GPL-2.0-or-later
0008 */
0009 
0010 #include "mymoneyreport_p.h"
0011 
0012 // ----------------------------------------------------------------------------
0013 // QT Includes
0014 
0015 // ----------------------------------------------------------------------------
0016 // KDE Includes
0017 
0018 // ----------------------------------------------------------------------------
0019 // Project Includes
0020 
0021 #include "mymoneymoney.h"
0022 #include "mymoneyfile.h"
0023 #include "mymoneyaccount.h"
0024 #include "mymoneytransaction.h"
0025 #include "mymoneytransactionfilter.h"
0026 #include "mymoneyexception.h"
0027 
0028 MyMoneyReport::MyMoneyReport() :
0029     MyMoneyObject(*new MyMoneyReportPrivate)
0030 {
0031 }
0032 
0033 MyMoneyReport::MyMoneyReport(const QString &id) :
0034     MyMoneyObject(*new MyMoneyReportPrivate, id)
0035 {
0036 }
0037 
0038 MyMoneyReport::MyMoneyReport(eMyMoney::Report::RowType rt,
0039                              unsigned ct,
0040                              eMyMoney::TransactionFilter::Date dl,
0041                              eMyMoney::Report::DetailLevel ss,
0042                              const QString& name,
0043                              const QString& comment) :
0044     MyMoneyObject(*new MyMoneyReportPrivate)
0045 {
0046     Q_D(MyMoneyReport);
0047     d->m_name = name;
0048     d->m_comment = comment;
0049     d->m_detailLevel = ss;
0050     d->m_investmentSum = ct & eMyMoney::Report::QueryColumn::CapitalGain ? eMyMoney::Report::InvestmentSum::Sold : eMyMoney::Report::InvestmentSum::Period;
0051     d->m_reportType = d->rowTypeToReportType(rt);
0052     d->m_rowType = rt;
0053     d->m_dateLock = dl;
0054 
0055     //set report type
0056     if (d->m_reportType == eMyMoney::Report::ReportType::PivotTable)
0057         d->m_columnType = static_cast<eMyMoney::Report::ColumnType>(ct);
0058     if (d->m_reportType == eMyMoney::Report::ReportType::QueryTable)
0059         d->m_queryColumns = static_cast<eMyMoney::Report::QueryColumn>(ct);
0060     setDateFilter(dl);
0061 
0062     //throw exception if the type is inconsistent
0063     if (d->rowTypeToReportType(rt) == eMyMoney::Report::ReportType::Invalid ||
0064             d->m_reportType == eMyMoney::Report::ReportType::NoReport)
0065         throw MYMONEYEXCEPTION_CSTRING("Invalid report type");
0066 
0067     //add the corresponding account groups
0068     addAccountGroupsByRowType(rt);
0069     switch(rt) {
0070     case eMyMoney::Report::RowType::AssetLiability:
0071     case eMyMoney::Report::RowType::Account:
0072     case eMyMoney::Report::RowType::ExpenseIncome:
0073         d->m_showRowTotals = true;
0074         break;
0075     default:
0076         break;
0077     }
0078 
0079 #ifdef DEBUG_REPORTS
0080     QDebug out = qDebug();
0081     out << _name << toString(_rt) << toString(m_reportType);
0082     foreach(const eMyMoney::Account::Type accountType, m_accountGroups)
0083         out << MyMoneyeMyMoney::Account::accountTypeToString(accountType);
0084     if (m_accounts.size() > 0)
0085         out << m_accounts;
0086 #endif
0087 }
0088 
0089 MyMoneyReport::MyMoneyReport(const MyMoneyReport& other) :
0090     MyMoneyObject(*new MyMoneyReportPrivate(*other.d_func()), other.id()),
0091     MyMoneyTransactionFilter(other)
0092 {
0093 }
0094 
0095 MyMoneyReport::MyMoneyReport(const QString& id, const MyMoneyReport& other) :
0096     MyMoneyObject(*new MyMoneyReportPrivate(*other.d_func()), id),
0097     MyMoneyTransactionFilter(other)
0098 {
0099     Q_D(MyMoneyReport);
0100     d->m_movingAverageDays = 0;
0101     d->m_currentDateColumn = 0;
0102 }
0103 
0104 MyMoneyReport::~MyMoneyReport()
0105 {
0106 }
0107 
0108 void MyMoneyReport::addAccountGroupsByRowType(eMyMoney::Report::RowType rt)
0109 {
0110     //add the corresponding account groups
0111     switch(rt) {
0112     case eMyMoney::Report::RowType::AccountInfo:
0113     case eMyMoney::Report::RowType::AssetLiability:
0114         addAccountGroup(eMyMoney::Account::Type::Asset);
0115         addAccountGroup(eMyMoney::Account::Type::Liability);
0116         break;
0117 
0118     case eMyMoney::Report::RowType::Account:
0119         addAccountGroup(eMyMoney::Account::Type::Asset);
0120         addAccountGroup(eMyMoney::Account::Type::AssetLoan);
0121         addAccountGroup(eMyMoney::Account::Type::Cash);
0122         addAccountGroup(eMyMoney::Account::Type::Checkings);
0123         addAccountGroup(eMyMoney::Account::Type::CreditCard);
0124         if (m_expertMode)
0125             addAccountGroup(eMyMoney::Account::Type::Equity);
0126         addAccountGroup(eMyMoney::Account::Type::Expense);
0127         addAccountGroup(eMyMoney::Account::Type::Income);
0128         addAccountGroup(eMyMoney::Account::Type::Liability);
0129         addAccountGroup(eMyMoney::Account::Type::Loan);
0130         addAccountGroup(eMyMoney::Account::Type::Savings);
0131         addAccountGroup(eMyMoney::Account::Type::Stock);
0132         break;
0133 
0134     case eMyMoney::Report::RowType::ExpenseIncome:
0135         addAccountGroup(eMyMoney::Account::Type::Expense);
0136         addAccountGroup(eMyMoney::Account::Type::Income);
0137         break;
0138 
0139     //FIXME take this out once we have sorted out all issues regarding budget of assets and liabilities -- asoliverez@gmail.com
0140     case eMyMoney::Report::RowType::Budget:
0141     case eMyMoney::Report::RowType::BudgetActual:
0142         addAccountGroup(eMyMoney::Account::Type::Expense);
0143         addAccountGroup(eMyMoney::Account::Type::Income);
0144         break;
0145 
0146     //cash flow reports show splits for all account groups
0147     case eMyMoney::Report::RowType::CashFlow:
0148         addAccountGroup(eMyMoney::Account::Type::Expense);
0149         addAccountGroup(eMyMoney::Account::Type::Income);
0150         addAccountGroup(eMyMoney::Account::Type::Asset);
0151         addAccountGroup(eMyMoney::Account::Type::Liability);
0152         break;
0153     default:
0154         break;
0155     }
0156 }
0157 
0158 eMyMoney::Report::ReportType MyMoneyReport::reportType() const
0159 {
0160     Q_D(const MyMoneyReport);
0161     return d->m_reportType;
0162 }
0163 
0164 void MyMoneyReport::setReportType(eMyMoney::Report::ReportType rt)
0165 {
0166     Q_D(MyMoneyReport);
0167     d->m_reportType = rt;
0168 }
0169 
0170 QString MyMoneyReport::name() const
0171 {
0172     Q_D(const MyMoneyReport);
0173     return d->m_name;
0174 }
0175 
0176 void MyMoneyReport::setName(const QString& s)
0177 {
0178     Q_D(MyMoneyReport);
0179     d->m_name = s;
0180 }
0181 
0182 bool MyMoneyReport::isShowingRowTotals() const
0183 {
0184     Q_D(const MyMoneyReport);
0185     return (d->m_showRowTotals);
0186 }
0187 
0188 void MyMoneyReport::setShowingRowTotals(bool f)
0189 {
0190     Q_D(MyMoneyReport);
0191     d->m_showRowTotals = f;
0192 }
0193 
0194 bool MyMoneyReport::isShowingColumnTotals() const
0195 {
0196     Q_D(const MyMoneyReport);
0197     return d->m_showColumnTotals;
0198 }
0199 
0200 void MyMoneyReport::setShowingColumnTotals(bool f)
0201 {
0202     Q_D(MyMoneyReport);
0203     d->m_showColumnTotals = f;
0204 }
0205 
0206 eMyMoney::Report::RowType MyMoneyReport::rowType() const
0207 {
0208     Q_D(const MyMoneyReport);
0209     return d->m_rowType;
0210 }
0211 
0212 void MyMoneyReport::setRowType(eMyMoney::Report::RowType rt)
0213 {
0214     Q_D(MyMoneyReport);
0215     d->m_rowType = rt;
0216     d->m_reportType = d->rowTypeToReportType(rt);
0217 
0218     d->m_accountGroupFilter = false;
0219     d->m_accountGroups.clear();
0220 
0221     addAccountGroupsByRowType(rt);
0222 }
0223 
0224 bool MyMoneyReport::isRunningSum() const
0225 {
0226     Q_D(const MyMoneyReport);
0227     return (d->m_rowType == eMyMoney::Report::RowType::AssetLiability);
0228 }
0229 
0230 eMyMoney::Report::ColumnType MyMoneyReport::columnType() const
0231 {
0232     Q_D(const MyMoneyReport);
0233     return d->m_columnType;
0234 }
0235 
0236 void MyMoneyReport::setColumnType(eMyMoney::Report::ColumnType ct)
0237 {
0238     Q_D(MyMoneyReport);
0239     d->m_columnType = ct;
0240 }
0241 
0242 bool MyMoneyReport::isConvertCurrency() const
0243 {
0244     Q_D(const MyMoneyReport);
0245     return d->m_convertCurrency;
0246 }
0247 
0248 void MyMoneyReport::setConvertCurrency(bool f)
0249 {
0250     Q_D(MyMoneyReport);
0251     d->m_convertCurrency = f;
0252 }
0253 
0254 uint MyMoneyReport::columnPitch() const
0255 {
0256     Q_D(const MyMoneyReport);
0257     return static_cast<uint>(d->m_columnType);
0258 }
0259 
0260 QString MyMoneyReport::comment() const
0261 {
0262     Q_D(const MyMoneyReport);
0263     return d->m_comment;
0264 }
0265 
0266 void MyMoneyReport::setComment(const QString& comment)
0267 {
0268     Q_D(MyMoneyReport);
0269     d->m_comment = comment;
0270 }
0271 
0272 eMyMoney::Report::QueryColumn MyMoneyReport::queryColumns() const
0273 {
0274     Q_D(const MyMoneyReport);
0275     return d->m_queryColumns;
0276 }
0277 
0278 void MyMoneyReport::setQueryColumns(eMyMoney::Report::QueryColumn qc)
0279 {
0280     Q_D(MyMoneyReport);
0281     d->m_queryColumns = qc;
0282 }
0283 
0284 QString MyMoneyReport::group() const
0285 {
0286     Q_D(const MyMoneyReport);
0287     return d->m_group;
0288 }
0289 
0290 void MyMoneyReport::setGroup(const QString& group)
0291 {
0292     Q_D(MyMoneyReport);
0293     d->m_group = group;
0294 }
0295 
0296 bool MyMoneyReport::isFavorite() const
0297 {
0298     Q_D(const MyMoneyReport);
0299     return d->m_favorite;
0300 }
0301 
0302 void MyMoneyReport::setFavorite(bool f)
0303 {
0304     Q_D(MyMoneyReport);
0305     d->m_favorite = f;
0306 }
0307 
0308 bool MyMoneyReport::isTax() const
0309 {
0310     Q_D(const MyMoneyReport);
0311     return d->m_tax;
0312 }
0313 
0314 void MyMoneyReport::setTax(bool f)
0315 {
0316     Q_D(MyMoneyReport);
0317     d->m_tax = f;
0318 }
0319 
0320 bool MyMoneyReport::isInvestmentsOnly() const
0321 {
0322     Q_D(const MyMoneyReport);
0323     return d->m_investments;
0324 }
0325 
0326 void MyMoneyReport::setInvestmentsOnly(bool f)
0327 {
0328     Q_D(MyMoneyReport);
0329     d->m_investments = f;
0330     if (f) d->m_loans = false;
0331 }
0332 
0333 bool MyMoneyReport::isLoansOnly() const
0334 {
0335     Q_D(const MyMoneyReport);
0336     return d->m_loans;
0337 }
0338 
0339 void MyMoneyReport::setLoansOnly(bool f)
0340 {
0341     Q_D(MyMoneyReport);
0342     d->m_loans = f;
0343     if (f) d->m_investments = false;
0344 }
0345 
0346 eMyMoney::Report::DetailLevel MyMoneyReport::detailLevel() const
0347 {
0348     Q_D(const MyMoneyReport);
0349     return d->m_detailLevel;
0350 }
0351 
0352 void MyMoneyReport::setDetailLevel(eMyMoney::Report::DetailLevel detail)
0353 {
0354     Q_D(MyMoneyReport);
0355     d->m_detailLevel = detail;
0356 }
0357 
0358 eMyMoney::Report::InvestmentSum MyMoneyReport::investmentSum() const
0359 {
0360     Q_D(const MyMoneyReport);
0361     return d->m_investmentSum;
0362 }
0363 
0364 void MyMoneyReport::setInvestmentSum(eMyMoney::Report::InvestmentSum sum)
0365 {
0366     Q_D(MyMoneyReport);
0367     d->m_investmentSum = sum;
0368 }
0369 
0370 bool MyMoneyReport::isHideTransactions() const
0371 {
0372     Q_D(const MyMoneyReport);
0373     return d->m_hideTransactions;
0374 }
0375 
0376 void MyMoneyReport::setHideTransactions(bool f)
0377 {
0378     Q_D(MyMoneyReport);
0379     d->m_hideTransactions = f;
0380 }
0381 
0382 eMyMoney::Report::ChartType MyMoneyReport::chartType() const
0383 {
0384     Q_D(const MyMoneyReport);
0385     return d->m_chartType;
0386 }
0387 
0388 void MyMoneyReport::setChartType(eMyMoney::Report::ChartType type)
0389 {
0390     Q_D(MyMoneyReport);
0391     d->m_chartType = type;
0392 }
0393 
0394 eMyMoney::Report::ChartPalette MyMoneyReport::chartPalette() const
0395 {
0396     Q_D(const MyMoneyReport);
0397     return d->m_chartPalette;
0398 }
0399 
0400 void MyMoneyReport::setChartPalette(eMyMoney::Report::ChartPalette type)
0401 {
0402     Q_D(MyMoneyReport);
0403     d->m_chartPalette = type;
0404 }
0405 
0406 bool MyMoneyReport::isChartDataLabels() const
0407 {
0408     Q_D(const MyMoneyReport);
0409     return d->m_chartDataLabels;
0410 }
0411 
0412 void MyMoneyReport::setChartDataLabels(bool f)
0413 {
0414     Q_D(MyMoneyReport);
0415     d->m_chartDataLabels = f;
0416 }
0417 
0418 bool MyMoneyReport::isChartCHGridLines() const
0419 {
0420     Q_D(const MyMoneyReport);
0421     return d->m_chartCHGridLines;
0422 }
0423 
0424 void MyMoneyReport::setChartCHGridLines(bool f)
0425 {
0426     Q_D(MyMoneyReport);
0427     d->m_chartCHGridLines = f;
0428 }
0429 
0430 bool MyMoneyReport::isChartSVGridLines() const
0431 {
0432     Q_D(const MyMoneyReport);
0433     return d->m_chartSVGridLines;
0434 }
0435 
0436 void MyMoneyReport::setChartSVGridLines(bool f)
0437 {
0438     Q_D(MyMoneyReport);
0439     d->m_chartSVGridLines = f;
0440 }
0441 
0442 bool MyMoneyReport::isChartByDefault() const
0443 {
0444     Q_D(const MyMoneyReport);
0445     return d->m_chartByDefault;
0446 }
0447 
0448 void MyMoneyReport::setChartByDefault(bool f)
0449 {
0450     Q_D(MyMoneyReport);
0451     d->m_chartByDefault = f;
0452 }
0453 
0454 uint MyMoneyReport::chartLineWidth() const
0455 {
0456     Q_D(const MyMoneyReport);
0457     return d->m_chartLineWidth;
0458 }
0459 
0460 void MyMoneyReport::setChartLineWidth(uint f)
0461 {
0462     Q_D(MyMoneyReport);
0463     d->m_chartLineWidth = f;
0464 }
0465 
0466 bool MyMoneyReport::isLogYAxis() const
0467 {
0468     Q_D(const MyMoneyReport);
0469     return d->m_logYaxis;
0470 }
0471 
0472 void MyMoneyReport::setLogYAxis(bool f)
0473 {
0474     Q_D(MyMoneyReport);
0475     d->m_logYaxis = f;
0476 }
0477 
0478 bool MyMoneyReport::isNegExpenses() const
0479 {
0480     Q_D(const MyMoneyReport);
0481     return d->m_negExpenses;
0482 }
0483 
0484 void MyMoneyReport::setNegExpenses(bool f)
0485 {
0486     Q_D(MyMoneyReport);
0487     d->m_negExpenses = f;
0488 }
0489 
0490 QString MyMoneyReport::dataRangeStart() const
0491 {
0492     Q_D(const MyMoneyReport);
0493     return d->m_dataRangeStart;
0494 }
0495 
0496 void MyMoneyReport::setDataRangeStart(const QString& f)
0497 {
0498     Q_D(MyMoneyReport);
0499     d->m_dataRangeStart = f;
0500 }
0501 
0502 QString MyMoneyReport::dataRangeEnd() const
0503 {
0504     Q_D(const MyMoneyReport);
0505     return d->m_dataRangeEnd;
0506 }
0507 
0508 void MyMoneyReport::setDataRangeEnd(const QString& f)
0509 {
0510     Q_D(MyMoneyReport);
0511     d->m_dataRangeEnd = f;
0512 }
0513 
0514 QString MyMoneyReport::dataMajorTick() const
0515 {
0516     Q_D(const MyMoneyReport);
0517     return d->m_dataMajorTick;
0518 }
0519 
0520 void MyMoneyReport::setDataMajorTick(const QString& f)
0521 {
0522     Q_D(MyMoneyReport);
0523     d->m_dataMajorTick = f;
0524 }
0525 
0526 QString MyMoneyReport::dataMinorTick() const
0527 {
0528     Q_D(const MyMoneyReport);
0529     return d->m_dataMinorTick;
0530 }
0531 
0532 void MyMoneyReport::setDataMinorTick(const QString& f)
0533 {
0534     Q_D(MyMoneyReport);
0535     d->m_dataMinorTick = f;
0536 }
0537 
0538 uint MyMoneyReport::yLabelsPrecision() const
0539 {
0540     Q_D(const MyMoneyReport);
0541     return d->m_yLabelsPrecision;
0542 }
0543 
0544 void MyMoneyReport::setYLabelsPrecision(int f)
0545 {
0546     Q_D(MyMoneyReport);
0547     d->m_yLabelsPrecision = f;
0548 }
0549 
0550 bool MyMoneyReport::isIncludingSchedules() const
0551 {
0552     Q_D(const MyMoneyReport);
0553     return d->m_includeSchedules;
0554 }
0555 
0556 void MyMoneyReport::setIncludingSchedules(bool f)
0557 {
0558     Q_D(MyMoneyReport);
0559     d->m_includeSchedules = f;
0560 }
0561 
0562 bool MyMoneyReport::isColumnsAreDays() const
0563 {
0564     Q_D(const MyMoneyReport);
0565     return d->m_columnsAreDays;
0566 }
0567 
0568 void MyMoneyReport::setColumnsAreDays(bool f)
0569 {
0570     Q_D(MyMoneyReport);
0571     d->m_columnsAreDays = f;
0572 }
0573 
0574 bool MyMoneyReport::isIncludingTransfers() const
0575 {
0576     Q_D(const MyMoneyReport);
0577     return d->m_includeTransfers;
0578 }
0579 
0580 void MyMoneyReport::setIncludingTransfers(bool f)
0581 {
0582     Q_D(MyMoneyReport);
0583     d->m_includeTransfers = f;
0584 }
0585 
0586 bool MyMoneyReport::isIncludingUnusedAccounts() const
0587 {
0588     Q_D(const MyMoneyReport);
0589     return d->m_includeUnusedAccounts;
0590 }
0591 
0592 void MyMoneyReport::setIncludingUnusedAccounts(bool f)
0593 {
0594     Q_D(MyMoneyReport);
0595     d->m_includeUnusedAccounts = f;
0596 }
0597 
0598 bool MyMoneyReport::hasBudget() const
0599 {
0600     Q_D(const MyMoneyReport);
0601     return !d->m_budgetId.isEmpty();
0602 }
0603 
0604 QString MyMoneyReport::budget() const
0605 {
0606     Q_D(const MyMoneyReport);
0607     return d->m_budgetId;
0608 }
0609 
0610 /**
0611   * Sets the budget used for this report
0612   *
0613   * @param budget The ID of the budget to use, or an empty string
0614   * to indicate a budget is NOT included
0615   * @param fa Whether to display actual data alongside the budget.
0616   * Setting to false means the report displays ONLY the budget itself.
0617   * @warning For now, the budget ID is ignored.  The budget id is
0618   * simply checked for any non-empty string, and if so, hasBudget()
0619   * will return true.
0620   */
0621 void MyMoneyReport::setBudget(const QString& budget, bool fa)
0622 {
0623     Q_D(MyMoneyReport);
0624     d->m_budgetId = budget;
0625     d->m_includeBudgetActuals = fa;
0626 }
0627 
0628 bool MyMoneyReport::isIncludingBudgetActuals() const
0629 {
0630     Q_D(const MyMoneyReport);
0631     return d->m_includeBudgetActuals;
0632 }
0633 
0634 void MyMoneyReport::setIncludingBudgetActuals(bool f)
0635 {
0636     Q_D(MyMoneyReport);
0637     d->m_includeBudgetActuals = f;
0638 }
0639 
0640 bool MyMoneyReport::isIncludingForecast() const
0641 {
0642     Q_D(const MyMoneyReport);
0643     return d->m_includeForecast;
0644 }
0645 
0646 void MyMoneyReport::setIncludingForecast(bool f)
0647 {
0648     Q_D(MyMoneyReport);
0649     d->m_includeForecast = f;
0650 }
0651 
0652 bool MyMoneyReport::isIncludingMovingAverage() const
0653 {
0654     Q_D(const MyMoneyReport);
0655     return d->m_includeMovingAverage;
0656 }
0657 
0658 void MyMoneyReport::setIncludingMovingAverage(bool f)
0659 {
0660     Q_D(MyMoneyReport);
0661     d->m_includeMovingAverage = f;
0662 }
0663 
0664 int MyMoneyReport::movingAverageDays() const
0665 {
0666     Q_D(const MyMoneyReport);
0667     return d->m_movingAverageDays;
0668 }
0669 
0670 void MyMoneyReport::setMovingAverageDays(int days)
0671 {
0672     Q_D(MyMoneyReport);
0673     d->m_movingAverageDays = days;
0674 }
0675 
0676 bool MyMoneyReport::isIncludingPrice() const
0677 {
0678     Q_D(const MyMoneyReport);
0679     return d->m_includePrice;
0680 }
0681 
0682 void MyMoneyReport::setIncludingPrice(bool f)
0683 {
0684     Q_D(MyMoneyReport);
0685     d->m_includePrice = f;
0686 }
0687 
0688 bool MyMoneyReport::isIncludingAveragePrice() const
0689 {
0690     Q_D(const MyMoneyReport);
0691     return d->m_includeAveragePrice;
0692 }
0693 
0694 void MyMoneyReport::setIncludingAveragePrice(bool f)
0695 {
0696     Q_D(MyMoneyReport);
0697     d->m_includeAveragePrice = f;
0698 }
0699 
0700 eMyMoney::Report::DataLock MyMoneyReport::dataFilter() const
0701 {
0702     Q_D(const MyMoneyReport);
0703     return d->m_dataLock;
0704 }
0705 
0706 bool MyMoneyReport::isDataUserDefined() const
0707 {
0708     Q_D(const MyMoneyReport);
0709     return d->m_dataLock == eMyMoney::Report::DataLock::UserDefined;
0710 }
0711 
0712 void MyMoneyReport::setDataFilter(eMyMoney::Report::DataLock u)
0713 {
0714     Q_D(MyMoneyReport);
0715     d->m_dataLock = u;
0716 }
0717 
0718 eMyMoney::TransactionFilter::Date MyMoneyReport::dateRange() const
0719 {
0720     Q_D(const MyMoneyReport);
0721     return d->m_dateLock;
0722 }
0723 
0724 bool MyMoneyReport::isDateUserDefined() const
0725 {
0726     Q_D(const MyMoneyReport);
0727     return d->m_dateLock == eMyMoney::TransactionFilter::Date::UserDefined;
0728 }
0729 
0730 /**
0731   * Set the underlying date filter and LOCK that filter to the specified
0732   * range.  For example, if @p _u is "CurrentMonth", this report should always
0733   * be updated to the current month no matter when the report is run.
0734   *
0735   * This updating is not entirely automatic, you should update it yourself by
0736   * calling updateDateFilter.
0737   *
0738   * @param _u The date range constant (MyMoneyTransactionFilter::dateRangeE)
0739   *          which this report should be locked to.
0740   */
0741 
0742 void MyMoneyReport::setDateFilter(eMyMoney::TransactionFilter::Date u)
0743 {
0744     Q_D(MyMoneyReport);
0745     d->m_dateLock = u;
0746     if (u != eMyMoney::TransactionFilter::Date::UserDefined)
0747         MyMoneyTransactionFilter::setDateFilter(u);
0748 }
0749 
0750 void MyMoneyReport::setDateFilter(const QDate& db, const QDate& de)
0751 {
0752     MyMoneyTransactionFilter::setDateFilter(db, de);
0753 }
0754 
0755 void MyMoneyReport::updateDateFilter()
0756 {
0757     Q_D(MyMoneyReport);
0758     if (d->m_dateLock != eMyMoney::TransactionFilter::Date::UserDefined) MyMoneyTransactionFilter::setDateFilter(d->m_dateLock);
0759 }
0760 
0761 
0762 bool MyMoneyReport::isMixedTime() const
0763 {
0764     Q_D(const MyMoneyReport);
0765     return d->m_mixedTime;
0766 }
0767 
0768 void MyMoneyReport::setMixedTime(bool f)
0769 {
0770     Q_D(MyMoneyReport);
0771     d->m_mixedTime = f;
0772 }
0773 
0774 int MyMoneyReport::currentDateColumn() const
0775 {
0776     Q_D(const MyMoneyReport);
0777     return d->m_currentDateColumn;
0778 }
0779 
0780 void MyMoneyReport::setCurrentDateColumn(int f)
0781 {
0782     Q_D(MyMoneyReport);
0783     d->m_currentDateColumn = f;
0784 }
0785 
0786 uint MyMoneyReport::settlementPeriod() const
0787 {
0788     Q_D(const MyMoneyReport);
0789     return d->m_settlementPeriod;
0790 }
0791 
0792 void MyMoneyReport::setSettlementPeriod(uint days)
0793 {
0794     Q_D(MyMoneyReport);
0795     d->m_settlementPeriod = days;
0796 }
0797 
0798 bool MyMoneyReport::isShowingSTLTCapitalGains() const
0799 {
0800     Q_D(const MyMoneyReport);
0801     return d->m_showSTLTCapitalGains;
0802 }
0803 
0804 void MyMoneyReport::setShowSTLTCapitalGains(bool f)
0805 {
0806     Q_D(MyMoneyReport);
0807     d->m_showSTLTCapitalGains = f;
0808 }
0809 
0810 QDate MyMoneyReport::termSeparator() const
0811 {
0812     Q_D(const MyMoneyReport);
0813     return d->m_tseparator;
0814 }
0815 
0816 void MyMoneyReport::setTermSeparator(const QDate& date)
0817 {
0818     Q_D(MyMoneyReport);
0819     d->m_tseparator = date;
0820 }
0821 
0822 bool MyMoneyReport::isSkippingZero() const
0823 {
0824     Q_D(const MyMoneyReport);
0825     return d->m_skipZero;
0826 }
0827 
0828 void MyMoneyReport::setSkipZero(int f)
0829 {
0830     Q_D(MyMoneyReport);
0831     d->m_skipZero = f;
0832 }
0833 
0834 void MyMoneyReport::clearTransactionFilter()
0835 {
0836     Q_D(MyMoneyReport);
0837     d->m_accountGroupFilter = false;
0838     d->m_accountGroups.clear();
0839 
0840     MyMoneyTransactionFilter::clear();
0841 }
0842 
0843 void MyMoneyReport::assignFilter(const MyMoneyTransactionFilter& filter)
0844 {
0845     MyMoneyTransactionFilter::operator=(filter);
0846 }
0847 
0848 void MyMoneyReport::validDateRange(QDate& db, QDate& de)
0849 {
0850     db = fromDate();
0851     de = toDate();
0852 
0853     // if either begin or end date are invalid we have one of the following
0854     // possible date filters:
0855     //
0856     // a) begin date not set - first transaction until given end date
0857     // b) end date not set   - from given date until last transaction
0858     // c) both not set       - first transaction until last transaction
0859     //
0860     // If there is no transaction in the engine at all, we use the current
0861     // year as the filter criteria.
0862 
0863     if (!db.isValid() || !de.isValid()) {
0864         QList<MyMoneyTransaction> list = MyMoneyFile::instance()->transactionList(*this);
0865         QDate tmpBegin, tmpEnd;
0866 
0867         if (!list.isEmpty()) {
0868             qSort(list);
0869             // try to use the post dates
0870             tmpBegin = list.front().postDate();
0871             tmpEnd = list.back().postDate();
0872             // if the post dates are not valid try the entry dates
0873             if (!tmpBegin.isValid())
0874                 tmpBegin = list.front().entryDate();
0875             if (!tmpEnd.isValid())
0876                 tmpEnd = list.back().entryDate();
0877         }
0878         // make sure that we leave this function with valid dates no mather what
0879         if (!tmpBegin.isValid() || !tmpEnd.isValid() || tmpBegin > tmpEnd) {
0880             tmpBegin = QDate(QDate::currentDate().year(), 1, 1);   // the first date in the file
0881             tmpEnd = QDate(QDate::currentDate().year(), 12, 31);   // the last date in the file
0882         }
0883         if (!db.isValid())
0884             db = tmpBegin;
0885         if (!de.isValid())
0886             de = tmpEnd;
0887     }
0888     if (db > de)
0889         db = de;
0890 }
0891 
0892 bool MyMoneyReport::accountGroups(QList<eMyMoney::Account::Type>& list) const
0893 {
0894     Q_D(const MyMoneyReport);
0895     bool result = d->m_accountGroupFilter;
0896 
0897     if (result) {
0898         QList<eMyMoney::Account::Type>::const_iterator it_group = d->m_accountGroups.begin();
0899         while (it_group != d->m_accountGroups.end()) {
0900             list += (*it_group);
0901             ++it_group;
0902         }
0903     }
0904     return result;
0905 }
0906 
0907 void MyMoneyReport::addAccountGroup(eMyMoney::Account::Type type)
0908 {
0909     Q_D(MyMoneyReport);
0910     if (!d->m_accountGroups.isEmpty() && type != eMyMoney::Account::Type::Unknown) {
0911         if (d->m_accountGroups.contains(type))
0912             return;
0913     }
0914     d->m_accountGroupFilter = true;
0915     if (type != eMyMoney::Account::Type::Unknown)
0916         d->m_accountGroups.push_back(type);
0917 }
0918 
0919 bool MyMoneyReport::includesAccountGroup(eMyMoney::Account::Type type) const
0920 {
0921     Q_D(const MyMoneyReport);
0922     bool result = (! d->m_accountGroupFilter)
0923                   || (isIncludingTransfers() && d->m_rowType == eMyMoney::Report::RowType::ExpenseIncome)
0924                   || d->m_accountGroups.contains(type);
0925 
0926     return result;
0927 }
0928 
0929 bool MyMoneyReport::includes(const MyMoneyAccount& acc) const
0930 {
0931     Q_D(const MyMoneyReport);
0932     auto result = false;
0933 
0934     if (includesAccountGroup(acc.accountGroup())) {
0935         switch (acc.accountGroup()) {
0936         case eMyMoney::Account::Type::Income:
0937         case eMyMoney::Account::Type::Expense:
0938             if (isTax())
0939                 result = (acc.value("Tax") == "Yes") && includesCategory(acc.id());
0940             else
0941                 result = includesCategory(acc.id());
0942             break;
0943         case eMyMoney::Account::Type::Asset:
0944         case eMyMoney::Account::Type::Liability:
0945             if (isLoansOnly())
0946                 result = acc.isLoan() && includesAccount(acc.id());
0947             else if (isInvestmentsOnly())
0948                 result = acc.isInvest() && includesAccount(acc.id());
0949             else if (isIncludingTransfers() && d->m_rowType == eMyMoney::Report::RowType::ExpenseIncome)
0950                 // If transfers are included, ONLY include this account if it is NOT
0951                 // included in the report itself!!
0952                 result = ! includesAccount(acc.id());
0953             else
0954                 result = includesAccount(acc.id());
0955             break;
0956         case eMyMoney::Account::Type::Equity:
0957             if (isInvestmentsOnly())
0958                 result = (isIncludingPrice() || isIncludingAveragePrice()) && acc.isInvest() && includesAccount(acc.id());
0959             break;
0960         default:
0961             result = includesAccount(acc.id());
0962         }
0963     }
0964     return result;
0965 }
0966 
0967 bool MyMoneyReport::hasReferenceTo(const QString& id) const
0968 {
0969     QStringList list;
0970 
0971     // collect all ids
0972     accounts(list);
0973     categories(list);
0974     payees(list);
0975     tags(list);
0976 
0977     return list.contains(id);
0978 }
0979 
0980 int MyMoneyReport::m_lineWidth = 2;
0981 bool MyMoneyReport::m_expertMode = false;
0982 
0983 void MyMoneyReport::setLineWidth(int width)
0984 {
0985     m_lineWidth = width;
0986 }
0987 
0988 int MyMoneyReport::lineWidth()
0989 {
0990     return m_lineWidth;
0991 }
0992 
0993 void MyMoneyReport::setExpertMode(bool expertMode)
0994 {
0995     m_expertMode = expertMode;
0996 }
0997 
0998 QString MyMoneyReport::toString(eMyMoney::Report::RowType type)
0999 {
1000     switch(type) {
1001     case eMyMoney::Report::RowType::NoRows             :
1002         return "eMyMoney::Report::RowType::NoRows";
1003     case eMyMoney::Report::RowType::AssetLiability     :
1004         return "eMyMoney::Report::RowType::AssetLiability";
1005     case eMyMoney::Report::RowType::ExpenseIncome      :
1006         return "eMyMoney::Report::RowType::ExpenseIncome";
1007     case eMyMoney::Report::RowType::Category           :
1008         return "eMyMoney::Report::RowType::Category";
1009     case eMyMoney::Report::RowType::TopCategory        :
1010         return "eTopCategory";
1011     case eMyMoney::Report::RowType::Account            :
1012         return "eAccount";
1013     case eMyMoney::Report::RowType::Tag                :
1014         return "eTag";
1015     case eMyMoney::Report::RowType::Payee              :
1016         return "ePayee";
1017     case eMyMoney::Report::RowType::Month              :
1018         return "eMonth";
1019     case eMyMoney::Report::RowType::Week               :
1020         return "eWeek";
1021     case eMyMoney::Report::RowType::TopAccount         :
1022         return "eTopAccount";
1023     case eMyMoney::Report::RowType::AccountByTopAccount:
1024         return "eAccountByTopAccount";
1025     case eMyMoney::Report::RowType::EquityType         :
1026         return "eEquityType";
1027     case eMyMoney::Report::RowType::AccountType        :
1028         return "eAccountType";
1029     case eMyMoney::Report::RowType::Institution        :
1030         return "eInstitution";
1031     case eMyMoney::Report::RowType::Budget             :
1032         return "eBudget";
1033     case eMyMoney::Report::RowType::BudgetActual       :
1034         return "eBudgetActual";
1035     case eMyMoney::Report::RowType::Schedule           :
1036         return "eSchedule";
1037     case eMyMoney::Report::RowType::AccountInfo        :
1038         return "eAccountInfo";
1039     case eMyMoney::Report::RowType::AccountLoanInfo    :
1040         return "eAccountLoanInfo";
1041     case eMyMoney::Report::RowType::AccountReconcile   :
1042         return "eAccountReconcile";
1043     case eMyMoney::Report::RowType::CashFlow           :
1044         return "eCashFlow";
1045     default                  :
1046         return "undefined";
1047     }
1048 }
1049 
1050 QString MyMoneyReport::toString(eMyMoney::Report::ReportType type)
1051 {
1052     switch(type) {
1053     case eMyMoney::Report::ReportType::NoReport:
1054         return "eNoReport";
1055     case eMyMoney::Report::ReportType::PivotTable:
1056         return "ePivotTable";
1057     case eMyMoney::Report::ReportType::QueryTable:
1058         return "eQueryTable";
1059     case eMyMoney::Report::ReportType::InfoTable:
1060         return "eInfoTable";
1061     default:
1062         return "undefined";
1063     }
1064 }