wxString mmReportSummaryByDate::getHTMLText() { int i = 0, j; double balancePerDay[5]; mmHTMLBuilder hb; wxString datePrec; wxDate date, dateStart = wxDate::Now(), dateEnd = wxDate::Now(); wxDateSpan span; mmHistoryItem *pHistItem; mmHistoryData arHistory; std::vector<balanceMap> balanceMapVec(Model_Account::instance().all().size()); std::vector<std::map<wxDate, double>::const_iterator> arIt(balanceMapVec.size()); std::vector<double> arBalance(balanceMapVec.size()); std::vector<wxString> totBalanceData; std::vector<wxDate> arDates; hb.init(); hb.addDivContainer(); hb.addHeader(2, wxString::Format(_("Accounts Balance - %s"), mode_==0 ? _("Monthly Report"):_("Yearly Report"))); hb.addDateNow(); hb.addLineBreak(); hb.startTable(); hb.startThead(); hb.startTableRow(); hb.addTableHeaderCell(_("Date")); hb.addTableHeaderCell(_("Cash"), true); hb.addTableHeaderCell(_("Bank Accounts"), true); hb.addTableHeaderCell(_("Credit Card Accounts"), true); hb.addTableHeaderCell(_("Term Accounts"), true); hb.addTableHeaderCell(_("Total"), true); hb.addTableHeaderCell(_("Stocks"), true); hb.addTableHeaderCell(_("Balance"), true); hb.endTableRow(); hb.endDiv(); hb.endThead(); for (const auto& account: Model_Account::instance().all()) { if (Model_Account::type(account) != Model_Account::INVESTMENT) { // in balanceMapVec ci sono i totali dei movimenti giorno per giorno const Model_Currency::Data* currency = Model_Account::currency(account); for (const auto& tran: Model_Account::transaction(account)) balanceMapVec[i][Model_Checking::TRANSDATE(tran)] += Model_Checking::balance(tran, account.ACCOUNTID) * Model_CurrencyHistory::getDayRate(currency->id(), tran.TRANSDATE); if (Model_Account::type(account) != Model_Account::TERM && balanceMapVec[i].size()) { date = balanceMapVec[i].begin()->first; if (date.IsEarlierThan(dateStart)) dateStart = date; } arBalance[i] = account.INITIALBAL * Model_CurrencyHistory::getDayRate(currency->id(), dateStart.FormatISODate()); } else { Model_Stock::Data_Set stocks = Model_Stock::instance().find(Model_Stock::HELDAT(account.id())); for (const auto & stock : stocks) { arHistory.resize(arHistory.size() + 1); pHistItem = arHistory.data() + arHistory.size() - 1; pHistItem->acctId = account.id(); pHistItem->stockId = stock.STOCKID; pHistItem->purchasePrice = stock.PURCHASEPRICE; pHistItem->purchaseDate = Model_Stock::PURCHASEDATE(stock); pHistItem->purchaseDateStr = stock.PURCHASEDATE; pHistItem->numShares = stock.NUMSHARES; pHistItem->stockHist = Model_StockHistory::instance().find(Model_StockHistory::SYMBOL(stock.SYMBOL)); std::stable_sort(pHistItem->stockHist.begin(), pHistItem->stockHist.end(), SorterByDATE()); std::reverse(pHistItem->stockHist.begin(), pHistItem->stockHist.end()); } } i++; } if (mode_ == 0) { dateEnd -= wxDateSpan::Months(1); dateEnd.SetToLastMonthDay(dateEnd.GetMonth(), dateEnd.GetYear()); span = wxDateSpan::Months(1); } else if (mode_ == 1) { dateEnd.Set(31, wxDateTime::Dec, wxDateTime::Now().GetYear()); span = wxDateSpan::Years(1); } else wxASSERT(0); date = dateEnd; while (date.IsLaterThan(dateStart)) date -= span; dateStart = date; i = 0; for (const auto& acctMap: balanceMapVec) arIt[i++] = acctMap.begin(); // prepare the dates array while (dateStart <= dateEnd) { if (mode_ == 0) dateStart.SetToLastMonthDay(dateStart.GetMonth(), dateStart.GetYear()); arDates.push_back(dateStart); dateStart += span; } date = wxDate::Today(); if (date.GetDay() != dateEnd.GetDay() || date.GetMonth() != dateEnd.GetMonth() || date.GetYear() != dateEnd.GetYear()) arDates.push_back(date); for (const auto & dateStart : arDates) { i = 0; for (auto& account: Model_Account::instance().all()) { if (Model_Account::type(account) != Model_Account::INVESTMENT) { for (; arIt[i] != balanceMapVec[i].end(); ++arIt[i]) { if (arIt[i]->first.IsLaterThan(dateStart)) break; arBalance[i] += arIt[i]->second; } } else { double convRate = 1.0; Model_Currency::Data* currency = Model_Account::currency(account); if (currency) convRate = Model_CurrencyHistory::getDayRate(currency->id(), dateStart.FormatISODate()); arBalance[i] = arHistory.getDailyBalanceAt(&account, dateStart) * convRate; } i++; } totBalanceData.push_back(dateStart.FormatISODate()); for (j=0; j<5; j++) balancePerDay[j] = 0.0; for (j=0; j<5; j++) { i = 0; for (const auto& account: Model_Account::instance().all()) { if ((j == 0 && Model_Account::type(account) == Model_Account::CASH) || (j == 1 && Model_Account::type(account) == Model_Account::CHECKING) || (j == 2 && Model_Account::type(account) == Model_Account::CREDIT_CARD) || (j == 3 && Model_Account::type(account) == Model_Account::TERM) || (j == 4 && Model_Account::type(account) == Model_Account::INVESTMENT)) { balancePerDay[j] += arBalance[i]; } i++; } totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[j])); } totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[0] + balancePerDay[1] + balancePerDay[2] + balancePerDay[3])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[0] + balancePerDay[1] + balancePerDay[2] + balancePerDay[3] + balancePerDay[4])); } hb.startTbody(); for (i = totBalanceData.size() - 8; i >= 0; i -= 8) { if (datePrec.Left(4) != totBalanceData[i].Left(4)) { hb.startTotalTableRow(); hb.addTableCell(totBalanceData[i].Left(4)); hb.addTableCell(""); hb.addTableCell(""); hb.addTableCell(""); hb.addTableCell(""); hb.addTableCell(""); hb.addTableCell(""); hb.addTableCell(""); hb.endTableRow(); } hb.startTableRow(); hb.addTableCell(mmGetDateForDisplay(mmGetStorageStringAsDate(totBalanceData[i]))); hb.addTableCell(totBalanceData[i + 1], true); hb.addTableCell(totBalanceData[i + 2], true); hb.addTableCell(totBalanceData[i + 3], true); hb.addTableCell(totBalanceData[i + 4], true); hb.addTableCell(totBalanceData[i + 6], true); hb.addTableCell(totBalanceData[i + 5], true); hb.addTableCell(totBalanceData[i + 7], true); hb.endTableRow(); datePrec = totBalanceData[i]; } hb.endTbody(); hb.endTable(); hb.end(); Model_Report::outputReportFile(hb.getHTMLText()); return ""; }
wxString mmReportSummaryByDate::getHTMLText() { size_t account_types_num = Model_Account::INVESTMENT + 1; std::map<size_t, double> balancePerDay; mmHTMLBuilder hb; wxString datePrec; wxDate date, dateStart = wxDate::Today(), dateEnd = wxDate::Today(); wxDateSpan span; mmHistoryItem *pHistItem; mmHistoryData arHistory; std::vector<balanceMap> balanceMapVec(Model_Account::instance().all().size()); std::vector<std::map<wxDate, double>::const_iterator> arIt(balanceMapVec.size()); std::vector<double> arBalance(balanceMapVec.size()); std::vector<wxString> totBalanceData; std::vector<wxDate> arDates; hb.init(); hb.addDivContainer(); hb.addHeader(2, wxString::Format(_("Accounts Balance - %s") , mode_ == 0 ? _("Monthly Report") : _("Yearly Report"))); hb.addDateNow(); hb.addLineBreak(); hb.startTable(); hb.startThead(); hb.startTableRow(); hb.addTableHeaderCell(_("Date")); hb.addTableHeaderCell(_("Cash"), true); hb.addTableHeaderCell(_("Bank Accounts"), true); hb.addTableHeaderCell(_("Credit Card Accounts"), true); hb.addTableHeaderCell(_("Loan Accounts"), true); hb.addTableHeaderCell(_("Term Accounts"), true); hb.addTableHeaderCell(_("Crypto Wallets"), true); hb.addTableHeaderCell(_("Total"), true); hb.addTableHeaderCell(_("Stocks"), true); hb.addTableHeaderCell(_("Balance"), true); hb.endTableRow(); hb.endDiv(); hb.endThead(); int i = 0; for (const auto& account: Model_Account::instance().all()) { if (Model_Account::type(account) != Model_Account::INVESTMENT) { // in balanceMapVec ci sono i totali dei movimenti giorno per giorno const Model_Currency::Data* currency = Model_Account::currency(account); for (const auto& tran : Model_Account::transaction(account)) { balanceMapVec[i][Model_Checking::TRANSDATE(tran)] += Model_Checking::balance(tran, account.ACCOUNTID) * Model_CurrencyHistory::getDayRate(currency->id(), tran.TRANSDATE); } if (Model_Account::type(account) != Model_Account::TERM && balanceMapVec[i].size()) { date = balanceMapVec[i].begin()->first; if (date.IsEarlierThan(dateStart)) { dateStart = date; } } arBalance[i] = account.INITIALBAL * Model_CurrencyHistory::getDayRate(currency->id(), dateStart); } else { Model_Stock::Data_Set stocks = Model_Stock::instance().find(Model_Stock::HELDAT(account.id())); for (const auto & stock : stocks) { arHistory.resize(arHistory.size() + 1); pHistItem = arHistory.data() + arHistory.size() - 1; pHistItem->acctId = account.id(); pHistItem->stockId = stock.STOCKID; pHistItem->purchasePrice = stock.PURCHASEPRICE; pHistItem->purchaseDate = Model_Stock::PURCHASEDATE(stock); pHistItem->purchaseDateStr = stock.PURCHASEDATE; pHistItem->numShares = stock.NUMSHARES; pHistItem->stockHist = Model_StockHistory::instance().find(Model_StockHistory::SYMBOL(stock.SYMBOL)); std::stable_sort(pHistItem->stockHist.begin(), pHistItem->stockHist.end(), SorterByDATE()); std::reverse(pHistItem->stockHist.begin(), pHistItem->stockHist.end()); } } i++; } if (mode_ == 0) { dateEnd -= wxDateSpan::Months(1); dateEnd.SetToLastMonthDay(dateEnd.GetMonth(), dateEnd.GetYear()); span = wxDateSpan::Months(1); } else if (mode_ == 1) { dateEnd.Set(31, wxDateTime::Dec, wxDateTime::Now().GetYear()); span = wxDateSpan::Years(1); } else { wxFAIL_MSG("unknown report mode"); } date = dateEnd; while (date.IsLaterThan(dateStart)) { date -= span; } dateStart = date; int c = 0; for (const auto& acctMap : balanceMapVec) { arIt[c++] = acctMap.begin(); } // prepare the dates array while (dateStart <= dateEnd) { if (mode_ == 0) { dateStart.SetToLastMonthDay(dateStart.GetMonth(), dateStart.GetYear()); } arDates.push_back(dateStart); dateStart += span; } date = wxDate::Today().SetToLastMonthDay(); if (date.GetDay() != dateEnd.GetDay() || date.GetMonth() != dateEnd.GetMonth() || date.GetYear() != dateEnd.GetYear()) { arDates.push_back(date); } for (const auto & dd : arDates) { int k = 0; double total = 0.0; for (auto& account: Model_Account::instance().all()) { if (Model_Account::type(account) != Model_Account::INVESTMENT) { for (; arIt[k] != balanceMapVec[k].end(); ++arIt[k]) { if (arIt[k]->first.IsLaterThan(dd)) { break; } arBalance[k] += arIt[k]->second; } } else { double convRate = 1.0; Model_Currency::Data* currency = Model_Account::currency(account); if (currency) { convRate = Model_CurrencyHistory::getDayRate(currency->id(), dd); } arBalance[k] = arHistory.getDailyBalanceAt(&account, dd) * convRate; } k++; } // prepare columns for report: date, cash, checking, credit card, term, partial total, investment, grand total totBalanceData.push_back(dd.FormatISODate()); for (size_t j = 0; j < account_types_num; j++) { balancePerDay[j] = 0.0; } int a = 0; for (const auto& account: Model_Account::instance().all()) { double t = arBalance[a++]; balancePerDay[Model_Account::type(account)] += t; } totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::CASH])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::CHECKING])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::CREDIT_CARD])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::LOAN])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::TERM])); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::CRYPTO])); total = balancePerDay[Model_Account::CASH] + balancePerDay[Model_Account::CHECKING] + balancePerDay[Model_Account::CREDIT_CARD] + balancePerDay[Model_Account::LOAN] + balancePerDay[Model_Account::TERM] + balancePerDay[Model_Account::CRYPTO]; totBalanceData.push_back(Model_Currency::toCurrency(total)); totBalanceData.push_back(Model_Currency::toCurrency(balancePerDay[Model_Account::INVESTMENT])); total += balancePerDay[Model_Account::INVESTMENT]; totBalanceData.push_back(Model_Currency::toCurrency(total)); } hb.startTbody(); int x = 1 + (account_types_num) + 2; for (int k = totBalanceData.size() - x; k >= 0; k -= x) { if (datePrec.Left(4) != totBalanceData[k].Left(4)) { hb.startTotalTableRow(); hb.addTableCell(totBalanceData[k].Left(4)); hb.addEmptyTableCell(x-1); hb.endTableRow(); } hb.startTableRow(); hb.addTableCellDate(totBalanceData[k]); for (int j = 0; j < x - 1; j++) { hb.addTableCell(totBalanceData[k + j + 1], true); } hb.endTableRow(); datePrec = totBalanceData[k]; } hb.endTbody(); hb.endTable(); hb.end(); return hb.getHTMLText(); }