Skip to content

Commit

Permalink
feat(#5685): add charts to Transaction Report
Browse files Browse the repository at this point in the history
  • Loading branch information
gabriele-v committed Jan 6, 2024
1 parent 12538ed commit 82159ec
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 3 deletions.
58 changes: 57 additions & 1 deletion src/filtertransdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,13 @@ static const wxString COLUMN_NAMES[] = { "ID", "Color", "Date", "Number", "Accou
static const wxString TRANSACTION_STATUSES[] = { wxTRANSLATE("Unreconciled"), wxTRANSLATE("Reconciled"), wxTRANSLATE("Void"),
wxTRANSLATE("Follow Up"), wxTRANSLATE("Duplicate"), wxTRANSLATE("All Except Reconciled") };

static const wxString GROUPBY_OPTIONS[] = { wxTRANSLATE("Account"), wxTRANSLATE("Payee"), wxTRANSLATE("Category"), wxTRANSLATE("Type") };
static const wxString GROUPBY_OPTIONS[] = { wxTRANSLATE("Account"), wxTRANSLATE("Payee"), wxTRANSLATE("Category"), wxTRANSLATE("Type"),
wxTRANSLATE("Day"), wxTRANSLATE("Month"), wxTRANSLATE("Year") };

static const wxString CHART_OPTIONS[] = { wxTRANSLATE("Bar"), wxTRANSLATE("Line"), wxTRANSLATE("Line DateTime"),
wxTRANSLATE("Pie"), wxTRANSLATE("Donut"), wxTRANSLATE("Radar"),
wxTRANSLATE("Bar Line"), wxTRANSLATE("Stacked Bar Line"), wxTRANSLATE("Stacked Area")};
// Keep options aligned with HtmlBuilder GraphData::type

// Used to determine if we need to refresh the tag text ctrl after
// accelerator hints are shown which only occurs once.
Expand Down Expand Up @@ -440,6 +446,14 @@ void mmFilterTransactionsDialog::mmDoDataToControls(const wxString& json)
bGroupBy_->Enable(groupByCheckBox_->IsChecked() && isReportMode_);
bGroupBy_->SetStringSelection(s_groupBy);

// Chart
Value& j_chart = GetValueByPointerWithDefault(j_doc, "/CHART", "");
const wxString& s_chart = j_chart.IsString() ? wxString::FromUTF8(j_chart.GetString()) : "";
chartCheckBox_->SetValue(!s_chart.empty());
bChart_->Enable(chartCheckBox_->IsChecked() && isReportMode_);
bChart_->SetStringSelection(s_chart);

// Combine splits
Value& j_combineSplits = GetValueByPointerWithDefault(j_doc, "/COMBINE_SPLITS", "");
const bool& b_combineSplits = j_combineSplits.IsBool() ? j_combineSplits.GetBool() : false;
combineSplitsCheckBox_->SetValue(b_combineSplits);
Expand Down Expand Up @@ -704,6 +718,18 @@ void mmFilterTransactionsDialog::mmDoCreateControls()
presPanelSizer->Add(bGroupBy_, g_flagsExpand);
mmToolTip(bGroupBy_, _("Specify how the report should be grouped"));

// Chart
chartCheckBox_ = new wxCheckBox(presPanel, wxID_ANY, _("Chart"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
presPanelSizer->Add(chartCheckBox_, g_flagsH);

bChart_ = new wxChoice(presPanel, wxID_ANY);
for (const auto& i : CHART_OPTIONS)
{
bChart_->Append(wxGetTranslation(i), new wxStringClientData(i));
}
presPanelSizer->Add(bChart_, g_flagsExpand);
mmToolTip(bChart_, _("Specify which chart will be included in the report"));

// Compress Splits
combineSplitsCheckBox_ = new wxCheckBox(presPanel, wxID_ANY, _("Combine Splits"), wxDefaultPosition, wxDefaultSize, wxCHK_2STATE);
combineSplitsCheckBox_->SetMinSize(wxSize(-1, bGroupBy_->GetSize().GetHeight()));
Expand Down Expand Up @@ -789,10 +815,14 @@ void mmFilterTransactionsDialog::mmDoCreateControls()
{
groupByCheckBox_->Disable();
bGroupBy_->Disable();
chartCheckBox_->Disable();
bChart_->Disable();
showColumnsCheckBox_->Disable();
bHideColumns_->Disable();
groupByCheckBox_->Hide();
bGroupBy_->Hide();
chartCheckBox_->Hide();
bChart_->Hide();
showColumnsCheckBox_->Hide();
bHideColumns_->Hide();
combineSplitsCheckBox_->Hide();
Expand Down Expand Up @@ -877,6 +907,7 @@ void mmFilterTransactionsDialog::OnCheckboxClick(wxCommandEvent& event)
colorButton_->Enable(colorCheckBox_->IsChecked());
bHideColumns_->Enable(showColumnsCheckBox_->IsChecked());
bGroupBy_->Enable(groupByCheckBox_->IsChecked() && isReportMode_);
bChart_->Enable(chartCheckBox_->IsChecked() && isReportMode_);

event.Skip();
}
Expand Down Expand Up @@ -1036,6 +1067,12 @@ bool mmFilterTransactionsDialog::mmIsValuesCorrect() const
return false;
}

if (chartCheckBox_->IsChecked() && bChart_->GetSelection() == wxNOT_FOUND)
{
mmErrorDialogs::ToolTip4Object(bChart_, _("Invalid value"), _("Chart"), wxICON_ERROR);
return false;
}

if (!m_custom_fields->ValidateCustomValues(0))
{
return false;
Expand Down Expand Up @@ -1855,6 +1892,17 @@ const wxString mmFilterTransactionsDialog::mmGetJsonSetings(bool i18n) const
}
}

// Chart
if (chartCheckBox_->IsChecked())
{
const wxString chart = bChart_->GetStringSelection();
if (!chart.empty())
{
json_writer.Key((i18n ? _("Chart") : "CHART").utf8_str());
json_writer.String(chart.utf8_str());
}
}

// Compress Splits
const bool combineSplits = combineSplitsCheckBox_->IsChecked();
if (combineSplits)
Expand Down Expand Up @@ -1950,6 +1998,14 @@ int mmFilterTransactionsDialog::mmGetGroupBy() const
return by;
}

int mmFilterTransactionsDialog::mmGetChart() const
{
int by = -1;
if (chartCheckBox_->IsChecked())
by = bChart_->GetSelection();
return by;
}

void mmFilterTransactionsDialog::mmDoResetFilterStatus()
{
// m_custom_fields->ResetWidgetsChanged();
Expand Down
9 changes: 8 additions & 1 deletion src/filtertransdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,15 @@ class mmFilterTransactionsDialog: public wxDialog
GROUPBY_ACCOUNT,
GROUPBY_PAYEE,
GROUPBY_CATEGORY,
GROUPBY_TYPE
GROUPBY_TYPE,
GROUPBY_DAY,
GROUPBY_MONTH,
GROUPBY_YEAR
};
int mmGetGroupBy() const;

int mmGetChart() const;

const wxArrayInt mmGetAccountsID() const;
const wxArrayInt mmGetHideColumnsID() const;

Expand Down Expand Up @@ -203,6 +208,8 @@ class mmFilterTransactionsDialog: public wxDialog
wxButton* bHideColumns_ = nullptr;
wxCheckBox* groupByCheckBox_ = nullptr;
wxChoice* bGroupBy_ = nullptr;
wxCheckBox* chartCheckBox_ = nullptr;
wxChoice* bChart_ = nullptr;
wxCheckBox* combineSplitsCheckBox_ = nullptr;
private:
wxString m_settings_json;
Expand Down
3 changes: 2 additions & 1 deletion src/reports/htmlbuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ struct GraphSeries
struct GraphData
{
wxString title;
enum { BAR = 0, LINE, LINE_DATETIME, PIE, DONUT, RADAR, BARLINE, STACKEDBARLINE, STACKEDAREA } type;
enum GraphType { BAR = 0, LINE, LINE_DATETIME, PIE, DONUT, RADAR, BARLINE, STACKEDBARLINE, STACKEDAREA } type;
//Keep type aligned in FilterTransDialog CHART_OPTIONS
std::vector<wxString> labels;
std::vector<GraphSeries> series;
std::vector<wxColour> colors;
Expand Down
59 changes: 59 additions & 0 deletions src/reports/transactions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "util.h"
#include "model/allmodel.h"
#include <algorithm>
#include <numeric>
#include <vector>
#include <float.h>

Expand Down Expand Up @@ -127,6 +128,7 @@ table {
m_noOfCols = (m_transDialog->mmIsHideColumnsChecked()) ? m_transDialog->mmGetHideColumnsID().GetCount() : 11;
const wxString& AttRefType = Model_Attachment::reftype_desc(Model_Attachment::TRANSACTION);
const int groupBy = m_transDialog->mmGetGroupBy();
const int chart = m_transDialog->mmGetChart();
wxString lastSortLabel = "";

std::map<int, double> total; //Store transaction amount with original currency
Expand All @@ -135,6 +137,7 @@ table {
std::map<int, double> grand_total_in_base_curr; //Grad - Store transactions amount daily converted to base currency
std::map<int, double> grand_total_extrans; //Grand - Store transaction amount with original currency - excluding TRANSFERS
std::map<int, double> grand_total_in_base_curr_extrans; //Grand - Store transactions amount daily converted to base currency - excluding TRANSFERS
std::map<wxString, double> values_chart; // Store grouped values for chart

const wxString RefType = Model_Attachment::reftype_desc(Model_Attachment::TRANSACTION);
Model_CustomField::FIELDTYPE UDFC01_Type = Model_CustomField::getUDFCType(RefType, "UDFC01");
Expand All @@ -161,6 +164,12 @@ table {
sortLabel = transaction.CATEGNAME;
else if (groupBy == mmFilterTransactionsDialog::GROUPBY_TYPE)
sortLabel = wxGetTranslation(transaction.TRANSCODE);
else if (groupBy == mmFilterTransactionsDialog::GROUPBY_DAY)
sortLabel = mmGetDateForDisplay(transaction.TRANSDATE);
else if (groupBy == mmFilterTransactionsDialog::GROUPBY_MONTH)
sortLabel = Model_Checking::TRANSDATE(transaction).Format("%Y-%m");
else if (groupBy == mmFilterTransactionsDialog::GROUPBY_YEAR)
sortLabel = Model_Checking::TRANSDATE(transaction).Format("%Y");

if (sortLabel != lastSortLabel)
{
Expand All @@ -174,6 +183,13 @@ table {
hb.endTbody();
hb.endTable();
hb.endDiv();

if (chart > -1)
{
double value_chart = std::accumulate(total_in_base_curr.begin(), total_in_base_curr.end(), 0,
[](const double previous, decltype(*total_in_base_curr.begin()) p) { return previous + p.second; });
values_chart[lastSortLabel] += value_chart;
}
total.clear();
total_in_base_curr.clear();
}
Expand Down Expand Up @@ -287,6 +303,10 @@ table {
grand_total_extrans[curr->CURRENCYID] += amount;
grand_total_in_base_curr_extrans[curr->CURRENCYID] += amount * convRate;
}
if (chart > -1 && groupBy == -1)
{
values_chart[std::to_string(transaction.TRANSID)] += (amount * convRate);
}
}
else
{
Expand Down Expand Up @@ -378,11 +398,18 @@ table {
hb.startTable();
hb.startTbody();
displayTotals(total, total_in_base_curr, m_noOfCols);
if (chart > -1)
{
double value_chart = std::accumulate(total_in_base_curr.begin(), total_in_base_curr.end(), 0,
[](const double previous, decltype(*total_in_base_curr.begin()) p) { return previous + p.second; });
values_chart[lastSortLabel] += value_chart;
}
}
hb.endTbody();
hb.endTable();
hb.endDiv();

// Totals box
hb.addDivContainer("shadow");
{
hb.startTable();
Expand Down Expand Up @@ -426,6 +453,29 @@ table {
hb.endTable();
}
hb.endDiv();

// Chart
if (chart > -1 && values_chart.size() > 0)
{
hb.addDivContainer("shadow");
{
GraphData gd;
GraphSeries gs;
for (const auto& kv : values_chart)
{
gd.labels.push_back(kv.first);
gs.values.push_back(kv.second);
}
gd.series.push_back(gs);
//gd.colors = { mmThemeMetaColour(meta::COLOR_REPORT_DELTA) };
gd.type = static_cast<GraphData::GraphType>(chart);
hb.addChart(gd);
hb.end();
}
hb.endDiv();
}

// Filters recap
hb.addDivContainer("shadow");
{
m_transDialog->mmGetDescription(hb);
Expand Down Expand Up @@ -503,6 +553,15 @@ void mmReportTransactions::Run(wxSharedPtr<mmFilterTransactionsDialog>& dlg)
case mmFilterTransactionsDialog::GROUPBY_TYPE:
std::stable_sort(trans_.begin(), trans_.end(), SorterByTRANSCODE());
break;
case mmFilterTransactionsDialog::GROUPBY_DAY:
std::stable_sort(trans_.begin(), trans_.end(), SorterByTRANSDATE());
break;
case mmFilterTransactionsDialog::GROUPBY_MONTH:
std::stable_sort(trans_.begin(), trans_.end(), SorterByTRANSDATE());
break;
case mmFilterTransactionsDialog::GROUPBY_YEAR:
std::stable_sort(trans_.begin(), trans_.end(), SorterByTRANSDATE());
break;
}
}

Expand Down

0 comments on commit 82159ec

Please sign in to comment.