diff --git a/kmymoney/plugins/views/reports/reportsview.cpp b/kmymoney/plugins/views/reports/reportsview.cpp index eb4974655..23609e0e5 100644 --- a/kmymoney/plugins/views/reports/reportsview.cpp +++ b/kmymoney/plugins/views/reports/reportsview.cpp @@ -1,330 +1,331 @@ /*************************************************************************** reportsview.cpp ------------------- copyright : (C) 2018 by Łukasz Wojniłowicz email : lukasz.wojnilowicz@gmail.com ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "reportsview.h" // ---------------------------------------------------------------------------- // QT Includes // ---------------------------------------------------------------------------- // KDE Includes #include #include // ---------------------------------------------------------------------------- // Project Includes #include "viewinterface.h" #include "kreportsview.h" #include "kreportchartview.h" #include "kmymoneysettings.h" #include "pivottable.h" #include "pivotgrid.h" #include "mymoneyfile.h" #include "mymoneysecurity.h" #include "mymoneyenums.h" #include "reportsviewenums.h" #define VIEW_LEDGER "ledger" ReportsView::ReportsView(QObject *parent, const QVariantList &args) : KMyMoneyPlugin::Plugin(parent, "reportsview"/*must be the same as X-KDE-PluginInfo-Name*/), m_view(nullptr) { Q_UNUSED(args) setComponentName("reportsview", i18n("Reports view")); // For information, announce that we have been loaded. qDebug("Plugins: reportsview loaded"); } ReportsView::~ReportsView() { qDebug("Plugins: reportsview unloaded"); } void ReportsView::plug() { m_view = new KReportsView; viewInterface()->addView(m_view, i18n("Reports"), View::Reports); } void ReportsView::unplug() { viewInterface()->removeView(View::Reports); } QVariant ReportsView::requestData(const QString &arg, uint type) { switch(type) { case eWidgetPlugin::WidgetType::NetWorthForecast: return QVariant::fromValue(netWorthForecast()); case eWidgetPlugin::WidgetType::NetWorthForecastWithArgs: return QVariant::fromValue(netWorthForecast(arg)); case eWidgetPlugin::WidgetType::Budget: return QVariant(budget()); default: return QVariant(); } } QWidget *ReportsView::netWorthForecast() const { MyMoneyReport reportCfg = MyMoneyReport( eMyMoney::Report::RowType::AssetLiability, static_cast(eMyMoney::Report::ColumnType::Months), eMyMoney::TransactionFilter::Date::UserDefined, // overridden by the setDateFilter() call below eMyMoney::Report::DetailLevel::Total, i18n("Net Worth Forecast"), i18n("Generated Report")); reportCfg.setChartByDefault(true); reportCfg.setChartCHGridLines(false); reportCfg.setChartSVGridLines(false); reportCfg.setChartDataLabels(false); reportCfg.setChartType(eMyMoney::Report::ChartType::Line); reportCfg.setIncludingSchedules(false); reportCfg.addAccountGroup(eMyMoney::Account::Type::Asset); reportCfg.addAccountGroup(eMyMoney::Account::Type::Liability); reportCfg.setColumnsAreDays(true); reportCfg.setConvertCurrency(true); reportCfg.setIncludingForecast(true); reportCfg.setDateFilter(QDate::currentDate(), QDate::currentDate().addDays(+ 90)); reports::PivotTable table(reportCfg); auto chartWidget = new reports::KReportChartView(nullptr); table.drawChart(*chartWidget); return chartWidget; } QWidget *ReportsView::netWorthForecast(const QString &arg) const { const QStringList liArgs = arg.split(';'); if (liArgs.count() != 4) return new QWidget(); eMyMoney::Report::DetailLevel detailLevel[4] = { eMyMoney::Report::DetailLevel::All, eMyMoney::Report::DetailLevel::Top, eMyMoney::Report::DetailLevel::Group, eMyMoney::Report::DetailLevel::Total }; MyMoneyReport reportCfg = MyMoneyReport( eMyMoney::Report::RowType::AssetLiability, static_cast(eMyMoney::Report::ColumnType::Months), eMyMoney::TransactionFilter::Date::UserDefined, // overridden by the setDateFilter() call below detailLevel[liArgs.at(0).toInt()], i18n("Net Worth Forecast"), i18n("Generated Report")); reportCfg.setChartByDefault(true); reportCfg.setChartCHGridLines(false); reportCfg.setChartSVGridLines(false); reportCfg.setChartType(eMyMoney::Report::ChartType::Line); reportCfg.setIncludingSchedules(false); reportCfg.setColumnsAreDays( true ); reportCfg.setChartDataLabels(false); reportCfg.setConvertCurrency(true); reportCfg.setIncludingForecast(true); reportCfg.setDateFilter(QDate::currentDate(), QDate::currentDate().addDays(liArgs.at(2).toLongLong())); reports::PivotTable table(reportCfg); auto forecastChart = new reports::KReportChartView(nullptr); forecastChart->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); table.drawChart(*forecastChart); // Adjust the size forecastChart->resize(liArgs.at(2).toInt() - 10, liArgs.at(3).toInt()); forecastChart->show(); forecastChart->update(); return forecastChart; } QString ReportsView::budget() const { const auto file = MyMoneyFile::instance(); QString html; if (file->countBudgets() == 0) { html += QString(""); html += QString("
%1
").arg(i18n("You have no budgets to display.")); html += QString(""); return html; } auto prec = MyMoneyMoney::denomToPrec(file->baseCurrency().smallestAccountFraction()); bool isOverrun = false; int i = 0; //config report just like "Monthly Budgeted vs Actual MyMoneyReport reportCfg = MyMoneyReport( eMyMoney::Report::RowType::BudgetActual, static_cast(eMyMoney::Report::ColumnType::Months), eMyMoney::TransactionFilter::Date::CurrentMonth, eMyMoney::Report::DetailLevel::All, i18n("Monthly Budgeted vs. Actual"), i18n("Generated Report")); reportCfg.setBudget("Any", true); reports::PivotTable table(reportCfg); reports::PivotGrid grid = table.grid(); //div header html += "
" + i18n("Budget") + "
\n
 
\n"; //display budget summary html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += QString(""); MyMoneyMoney totalBudgetValue = grid.m_total[reports::eBudget].m_total; MyMoneyMoney totalActualValue = grid.m_total[reports::eActual].m_total; MyMoneyMoney totalBudgetDiffValue = grid.m_total[reports::eBudgetDiff].m_total; QString totalBudgetAmount = totalBudgetValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); QString totalActualAmount = totalActualValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); QString totalBudgetDiffAmount = totalBudgetDiffValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); html += QString("").arg(showColoredAmount(totalBudgetAmount, totalBudgetValue.isNegative())); html += QString("").arg(showColoredAmount(totalActualAmount, totalActualValue.isNegative())); html += QString("").arg(showColoredAmount(totalBudgetDiffAmount, totalBudgetDiffValue.isNegative())); html += ""; html += "
"; html += i18n("Current Month Summary"); html += "
"; html += i18n("Budgeted"); html += ""; html += i18n("Actual"); html += ""; html += i18n("Difference"); html += "
%1%1%1
"; //budget overrun html += "
 
\n"; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; html += ""; reports::PivotGrid::iterator it_outergroup = grid.begin(); + const int column = 0; while (it_outergroup != grid.end()) { i = 0; reports::PivotOuterGroup::iterator it_innergroup = (*it_outergroup).begin(); while (it_innergroup != (*it_outergroup).end()) { reports::PivotInnerGroup::iterator it_row = (*it_innergroup).begin(); while (it_row != (*it_innergroup).end()) { //column number is 1 because the report includes only current month - if (it_row.value()[reports::eBudgetDiff].value(1).isNegative()) { + if (it_row.value()[reports::eBudgetDiff].value(column).isNegative()) { //get report account to get the name later reports::ReportAccount rowname = it_row.key(); //write the outergroup if it is the first row of outergroup being shown if (i == 0) { html += ""; html += QString("").arg(MyMoneyAccount::accountTypeToString(rowname.accountType())); html += ""; } html += QString("").arg(i++ & 0x01 ? "even" : "odd"); //get values from grid - MyMoneyMoney actualValue = it_row.value()[reports::eActual][1]; - MyMoneyMoney budgetValue = it_row.value()[reports::eBudget][1]; - MyMoneyMoney budgetDiffValue = it_row.value()[reports::eBudgetDiff][1]; + MyMoneyMoney actualValue = it_row.value()[reports::eActual][column]; + MyMoneyMoney budgetValue = it_row.value()[reports::eBudget][column]; + MyMoneyMoney budgetDiffValue = it_row.value()[reports::eBudgetDiff][column]; //format amounts QString actualAmount = actualValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); QString budgetAmount = budgetValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); QString budgetDiffAmount = budgetDiffValue.formatMoney(file->baseCurrency().tradingSymbol(), prec); //account name html += QString(""; //show amounts html += QString("").arg(showColoredAmount(budgetAmount, budgetValue.isNegative())); html += QString("").arg(showColoredAmount(actualAmount, actualValue.isNegative())); html += QString("").arg(showColoredAmount(budgetDiffAmount, budgetDiffValue.isNegative())); html += ""; //set the flag that there are overruns isOverrun = true; } ++it_row; } ++it_innergroup; } ++it_outergroup; } //if no negative differences are found, then inform that if (isOverrun == false) { html += QString::fromLatin1("").arg(((i++ & 1) == 1) ? QLatin1String("even") : QLatin1String("odd")); html += QString::fromLatin1("").arg(i18n("No Budget Categories have been overrun")); html += ""; } html += "
"; html += i18n("Budget Overruns"); html += "
"; html += i18n("Account"); html += ""; html += i18n("Budgeted"); html += ""; html += i18n("Actual"); html += ""; html += i18n("Difference"); html += "
%1
") + link(VIEW_LEDGER, QString("?id=%1").arg(rowname.id()), QString()) + rowname.name() + linkend() + "%1%1%1
%1
"; return html; } QString ReportsView::showColoredAmount(const QString &amount, bool isNegative) const { if (isNegative) { //if negative, get the settings for negative numbers return QString("%2").arg(KMyMoneySettings::schemeColor(SchemeColor::Negative).name(), amount); } //if positive, return the same string return amount; } QString ReportsView::link(const QString& view, const QString& query, const QString& _title) const { QString titlePart; QString title(_title); if (!title.isEmpty()) titlePart = QString(" title=\"%1\"").arg(title.replace(QLatin1Char(' '), " ")); return QString("").arg(view, query, titlePart); } QString ReportsView::linkend() const { return QStringLiteral(""); } K_PLUGIN_FACTORY_WITH_JSON(ReportsViewFactory, "reportsview.json", registerPlugin();) #include "reportsview.moc"