/*************************************************************************** * Copyright (C) 2006, 2007 by Niklas Knutsson * * nq@altern.org * * * * 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. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #ifdef HAVE_CONFIG_H # include #endif #include "overtimereport.h" #include "budget.h" #include "account.h" #include "transaction.h" #include "recurrence.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include extern QString htmlize_string(QString str); extern double averageMonth(const QDate &date1, const QDate &date2); extern double averageYear(const QDate &date1, const QDate &date2); extern QDate addMonths(const QDate &date, int nmonths); struct month_info { double value; double count; QDate date; }; OverTimeReport::OverTimeReport(Budget *budg, QWidget *parent) : QWidget(parent), budget(budg) { setWFlags(getWFlags() | Qt::WDestructiveClose); QVBoxLayout *layout = new QVBoxLayout(this, 6, 6); KButtonBox *buttons = new KButtonBox(this); buttons->addStretch(1); saveButton = buttons->addButton(KStdGuiItem::saveAs()); printButton = buttons->addButton(KStdGuiItem::print()); buttons->layout(); layout->addWidget(buttons); htmlpart = new KHTMLPart(this); layout->addWidget(htmlpart->view()); KConfig *config = kapp->config(); config->setGroup("Over Time Report"); QGroupBox *settingsGroup = new QGroupBox(1, Qt::Horizontal, i18n("Options"), this); QWidget *settingsWidget = new QWidget(settingsGroup); QGridLayout *settingsLayout = new QGridLayout(settingsWidget, 2, 2, 0, 6); settingsLayout->addWidget(new QLabel(i18n("Source:"), settingsWidget), 0, 0); QHBoxLayout *choicesLayout = new QHBoxLayout(); settingsLayout->addLayout(choicesLayout, 0, 1); sourceCombo = new KComboBox(settingsWidget); sourceCombo->setEditable(false); sourceCombo->insertItem(i18n("Profits")); sourceCombo->insertItem(i18n("Expenses")); sourceCombo->insertItem(i18n("Incomes")); choicesLayout->addWidget(sourceCombo); categoryCombo = new KComboBox(settingsWidget); categoryCombo->setEditable(false); categoryCombo->insertItem(i18n("All Categories Combined")); categoryCombo->setEnabled(false); choicesLayout->addWidget(categoryCombo); descriptionCombo = new KComboBox(settingsWidget); descriptionCombo->setEditable(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); descriptionCombo->setEnabled(false); choicesLayout->addWidget(descriptionCombo); current_account = NULL; current_source = 0; settingsLayout->addWidget(new QLabel(i18n("Columns:"), settingsWidget), 1, 0); QHBoxLayout *enabledLayout = new QHBoxLayout(); settingsLayout->addLayout(enabledLayout, 1, 1); valueButton = new QCheckBox(i18n("Value"), settingsWidget); valueButton->setChecked(config->readBoolEntry("valueEnabled", true)); enabledLayout->addWidget(valueButton); dailyButton = new QCheckBox(i18n("Daily"), settingsWidget); dailyButton->setChecked(config->readBoolEntry("dailyAverageEnabled", true)); enabledLayout->addWidget(dailyButton); monthlyButton = new QCheckBox(i18n("Monthly"), settingsWidget); monthlyButton->setChecked(config->readBoolEntry("monthlyAverageEnabled", true)); enabledLayout->addWidget(monthlyButton); yearlyButton = new QCheckBox(i18n("Yearly"), settingsWidget); yearlyButton->setChecked(config->readBoolEntry("yearlyEnabled", false)); enabledLayout->addWidget(yearlyButton); countButton = new QCheckBox(i18n("Quantity"), settingsWidget); countButton->setChecked(config->readBoolEntry("transactionCountEnabled", true)); enabledLayout->addWidget(countButton); perButton = new QCheckBox(i18n("Average value"), settingsWidget); perButton->setChecked(config->readBoolEntry("valuePerTransactionEnabled", false)); enabledLayout->addWidget(perButton); enabledLayout->addStretch(1); layout->addWidget(settingsGroup); connect(valueButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(dailyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(monthlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(yearlyButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(countButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(perButton, SIGNAL(toggled(bool)), this, SLOT(updateDisplay())); connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(sourceChanged(int))); connect(categoryCombo, SIGNAL(activated(int)), this, SLOT(categoryChanged(int))); connect(descriptionCombo, SIGNAL(activated(int)), this, SLOT(descriptionChanged(int))); connect(sourceCombo, SIGNAL(activated(int)), this, SLOT(updateDisplay())); connect(saveButton, SIGNAL(clicked()), this, SLOT(save())); connect(printButton, SIGNAL(clicked()), this, SLOT(print())); } void OverTimeReport::descriptionChanged(int index) { current_description = ""; bool b_income = (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); if(index == 0) { if(b_income) current_source = 5; else current_source = 6; } else { if(!has_empty_description || index < descriptionCombo->count() - 1) current_description = descriptionCombo->text(index); if(b_income) current_source = 9; else current_source = 10; } updateDisplay(); } void OverTimeReport::categoryChanged(int index) { descriptionCombo->blockSignals(true); descriptionCombo->clear(); descriptionCombo->insertItem(i18n("All Descriptions Combined")); current_account = NULL; if(index == 0) { if(sourceCombo->currentItem() == 2) { current_source = 1; } else { current_source = 2; } descriptionCombo->setEnabled(false); } else { if(sourceCombo->currentItem() == 1) { int i = categoryCombo->currentItem() - 1; if(i < (int) budget->expensesAccounts.count()) { current_account = budget->expensesAccounts.at(i); } current_source = 6; } else { int i = categoryCombo->currentItem() - 1; if(i < (int) budget->incomesAccounts.count()) { current_account = budget->incomesAccounts.at(i); } current_source = 5; } has_empty_description = false; QMap descriptions; Transaction *trans = budget->transactions.first(); while(trans) { if((trans->fromAccount() == current_account || trans->toAccount() == current_account)) { if(trans->description().isEmpty()) has_empty_description = true; else descriptions[trans->description()] = true; } trans = budget->transactions.next(); } QMap::iterator it_e = descriptions.end(); for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { descriptionCombo->insertItem(it.key()); } if(has_empty_description) descriptionCombo->insertItem(i18n("No description")); descriptionCombo->setEnabled(true); } descriptionCombo->blockSignals(false); updateDisplay(); } void OverTimeReport::sourceChanged(int index) { categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); categoryCombo->clear(); descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); current_description = ""; current_account = NULL; categoryCombo->insertItem(i18n("All Categories Combined")); if(index == 2) { Account *account = budget->incomesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); account = budget->incomesAccounts.next(); } categoryCombo->setEnabled(true); current_source = 1; } else if(index == 1) { Account *account = budget->expensesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); account = budget->expensesAccounts.next(); } categoryCombo->setEnabled(true); current_source = 2; } else { categoryCombo->setEnabled(false); current_source = 0; } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); updateDisplay(); } void OverTimeReport::saveConfig() { KConfig *config = kapp->config(); ((KDialogBase*) parent())->saveDialogSize(*config, "Over Time Report"); config->setGroup("Over Time Report"); config->writeEntry("valueEnabled", valueButton->isChecked()); config->writeEntry("dailyAverageEnabled", dailyButton->isChecked()); config->writeEntry("monthlyAverageEnabled", monthlyButton->isChecked()); config->writeEntry("yearlyAverageEnabled", yearlyButton->isChecked()); config->writeEntry("transactionCountEnabled", countButton->isChecked()); config->writeEntry("valuePerTransactionEnabled", perButton->isChecked()); } void OverTimeReport::save() { KFileDialog *dialog = new KFileDialog(QString::null, QString::null, this, NULL, true); QStringList filter; filter << "text/html"; dialog->setMimeFilter(filter, "text/html"); dialog->setOperationMode(KFileDialog::Saving); dialog->setMode(KFile::File); if(dialog->exec() != QDialog::Accepted) {dialog->deleteLater(); return;} KURL url = dialog->selectedURL(); dialog->deleteLater(); if(url.isEmpty() && url.isValid()) return; if(url.isLocalFile()) { if(QFile::exists(url.path())) { if(KMessageBox::warningYesNo(this, i18n("The selected file already exists. Would you like to overwrite the old copy?")) != KMessageBox::Yes) return; } QFileInfo info(url.path()); if(info.isDir()) { KMessageBox::error(this, i18n("You selected a directory!")); return; } KSaveFile ofile(url.path(), 0660); if(ofile.status()) { ofile.abort(); KMessageBox::error(this, i18n("Couldn't open file for writing.")); return; } QTextStream &outf = *ofile.textStream(); outf.setEncoding(QTextStream::UnicodeUTF8); outf << source; if(ofile.status()) { ofile.abort(); KMessageBox::error(this, i18n("Error while writing file; file was not saved.")); return; } ofile.close(); if(ofile.status()) { KMessageBox::error(this, i18n("Error after saving file; data may not have been saved.")); return; } return; } KTempFile tf; tf.setAutoDelete(true); QTextStream &outf = *tf.textStream(); outf.setEncoding(QTextStream::UnicodeUTF8); outf << source; KIO::NetAccess::upload(tf.name(), url, this); } void OverTimeReport::print() { htmlpart->view()->print(); } void OverTimeReport::updateDisplay() { const KCalendarSystem *calSys = KGlobal::locale()->calendar(); int columns = 2; bool enabled[6]; enabled[0] = valueButton->isChecked(); enabled[1] = dailyButton->isChecked(); enabled[2] = monthlyButton->isChecked(); enabled[3] = yearlyButton->isChecked(); enabled[4] = countButton->isChecked(); enabled[5] = perButton->isChecked(); for(size_t i = 0; i < 6; i++) { if(enabled[i]) columns++; } QValueVector monthly_values; month_info *mi = NULL; QDate first_date; AccountType at = ACCOUNT_TYPE_EXPENSES; Account *account = NULL; int type = 0; QString title, valuetitle, pertitle; switch(current_source) { case 0: { type = 0; title = i18n("Profits"); pertitle = i18n("Average Profit"); valuetitle = title; break; } case 1: { title = i18n("Incomes"); pertitle = i18n("Average Income"); valuetitle = title; type = 1; at = ACCOUNT_TYPE_INCOMES; break; } case 2: { title = i18n("Expenses"); pertitle = i18n("Average Cost"); valuetitle = title; type = 1; at = ACCOUNT_TYPE_EXPENSES; break; } case 5: { account = current_account; title = i18n("Incomes: %1").arg(account->name()); pertitle = i18n("Average Income"); valuetitle = i18n("Incomes"); type = 2; at = ACCOUNT_TYPE_INCOMES; break; } case 6: { account = current_account; title = i18n("Expenses: %1").arg(account->name()); pertitle = i18n("Average Cost"); valuetitle = i18n("Expenses"); type = 2; at = ACCOUNT_TYPE_EXPENSES; break; } case 9: { account = current_account; title = i18n("Incomes: %2, %1").arg(account->name()).arg(current_description.isEmpty() ? i18n("No description") : current_description); pertitle = i18n("Average Income"); valuetitle = i18n("Incomes"); type = 3; at = ACCOUNT_TYPE_INCOMES; break; } case 10: { account = current_account; title = i18n("Expenses: %2, %1").arg(account->name()).arg(current_description.isEmpty() ? i18n("No description") : current_description); pertitle = i18n("Average Cost"); valuetitle = i18n("Expenses"); type = 3; at = ACCOUNT_TYPE_EXPENSES; break; } } Transaction *trans = budget->transactions.first(); QDate start_date; while(trans) { if(trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS || trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS) { start_date = trans->date(); if(calSys->day(start_date) > 1) { start_date = addMonths(start_date, 1); calSys->setYMD(start_date, calSys->year(start_date), calSys->month(start_date), 1); } break; } trans = budget->transactions.next(); } if(start_date.isNull() || start_date > QDate::currentDate()) start_date = QDate::currentDate(); if(calSys->month(start_date) == calSys->month(QDate::currentDate()) && calSys->year(start_date) == calSys->year(QDate::currentDate())) { start_date = addMonths(start_date, -1); calSys->setYMD(start_date, calSys->year(start_date), calSys->month(start_date), 1); } first_date = start_date; QDate curdate = calSys->addDays(QDate::currentDate(), -1); if(calSys->day(curdate) < calSys->daysInMonth(curdate)) { curdate = addMonths(curdate, -1); calSys->setYMD(curdate, calSys->year(curdate), calSys->month(curdate), calSys->daysInMonth(curdate)); } if(curdate <= first_date || (calSys->month(start_date) == calSys->month(curdate) && calSys->year(start_date) == calSys->year(curdate))) { curdate = QDate::currentDate(); } bool started = false; trans = budget->transactions.first(); while(trans && trans->date() <= curdate) { bool include = false; int sign = 1; if(!started && trans->date() >= first_date) started = true; if(started) { if((type == 1 && trans->fromAccount()->type() == at) || (type == 2 && trans->fromAccount() == account) || (type == 3 && trans->fromAccount() == account && trans->description() == current_description) || (type == 0 && trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = 1; else if(at == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; include = true; } else if((type == 1 && trans->toAccount()->type() == at) || (type == 2 && trans->toAccount() == account) || (type == 3 && trans->toAccount() == account && trans->description() == current_description) || (type == 0 && trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = -1; else if(at == ACCOUNT_TYPE_INCOMES) sign = -1; else sign = 1; include = true; } } if(include) { if(!mi || trans->date() > mi->date) { QDate newdate, olddate; calSys->setYMD(newdate, calSys->year(trans->date()), calSys->month(trans->date()), calSys->daysInMonth(trans->date())); if(mi) { olddate = addMonths(mi->date, 1); calSys->setYMD(olddate, calSys->year(olddate), calSys->month(olddate), calSys->daysInMonth(olddate)); } else { calSys->setYMD(olddate, calSys->year(first_date), calSys->month(first_date), calSys->daysInMonth(first_date)); } while(olddate < newdate) { monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->count = 0.0; mi->date = olddate; olddate = addMonths(olddate, 1); calSys->setYMD(olddate, calSys->year(olddate), calSys->month(olddate), calSys->daysInMonth(olddate)); } monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = trans->value() * sign; mi->count = trans->quantity(); mi->date = newdate; } else { mi->value += trans->value() * sign; mi->count += trans->quantity(); } } trans = budget->transactions.next(); } if(mi) { while(mi->date < curdate) { QDate newdate = addMonths(mi->date, 1); calSys->setYMD(newdate, calSys->year(newdate), calSys->month(newdate), calSys->daysInMonth(newdate)); monthly_values.append(month_info()); mi = &monthly_values.back(); mi->value = 0.0; mi->count = 0.0; mi->date = newdate; } } double scheduled_value = 0.0; double scheduled_count = 0.0; if(mi) { ScheduledTransaction *strans = budget->scheduledTransactions.first(); while(strans && strans->transaction()->date() <= mi->date) { trans = strans->transaction(); bool include = false; int sign = 1; if((type == 1 && trans->fromAccount()->type() == at) || (type == 2 && trans->fromAccount() == account) || (type == 3 && trans->fromAccount() == account && trans->description() == current_description) || (type == 0 && trans->fromAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = 1; else if(at == ACCOUNT_TYPE_INCOMES) sign = 1; else sign = -1; include = true; } else if((type == 1 && trans->toAccount()->type() == at) || (type == 2 && trans->toAccount() == account) || (type == 3 && trans->toAccount() == account && trans->description() == current_description) || (type == 0 && trans->toAccount()->type() != ACCOUNT_TYPE_ASSETS)) { if(type == 0) sign = -1; else if(at == ACCOUNT_TYPE_INCOMES) sign = -1; else sign = 1; include = true; } if(include) { int count = (strans->recurrence() ? strans->recurrence()->countOccurrences(mi->date) : 1); scheduled_value += (trans->value() * sign * count); scheduled_count += count * trans->quantity(); } strans = budget->scheduledTransactions.next(); } } double average_month = averageMonth(first_date, curdate); double average_year = averageYear(first_date, curdate); source = ""; QTextOStream outf(&source); outf << "" << '\n'; outf << "" << '\n'; outf << "\t" << '\n'; outf << "\t\t"; outf << htmlize_string(title); outf << "" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t" << '\n'; outf << "\t" << '\n'; outf << "\t" << '\n'; outf << "\t\t

" << htmlize_string(title) << "

" << '\n'; outf << "\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; bool use_footer1 = false; if(enabled[0]) { outf << "\t\t\t\t\t"; } if(enabled[1]) outf << "\t\t\t\t\t"; if(enabled[2]) outf << "\t\t\t\t\t"; if(enabled[3]) outf << "\t\t\t\t\t"; if(enabled[4]) { outf << "\t\t\t\t\t"; } if(enabled[5]) { outf << "\t\t\t\t\t"; } outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; outf << "\t\t\t" << '\n'; QValueVector::iterator it_b = monthly_values.begin(); QValueVector::iterator it_e = monthly_values.end(); if(it_e != it_b) --it_e; QValueVector::iterator it = monthly_values.end(); int year = 0; double yearly_value = 0.0, total_value = 0.0; double yearly_count = 0.0, total_count = 0.0; QDate year_date; bool first_year = true, first_month = true; bool multiple_months = monthly_values.size() > 1; bool multiple_years = multiple_months && calSys->year(first_date) != calSys->year(curdate); int i_count_frac = 0; double intpart = 0.0; while(it != it_b) { --it; if(modf(it->count, &intpart) != 0.0) { i_count_frac = 2; break; } } it = monthly_values.end(); while(it != it_b) { --it; outf << "\t\t\t\t" << '\n'; if(first_month || year != calSys->year(it->date)) { if(!first_month && multiple_years) { outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = 1; if(first_year) { days = calSys->dayOfYear(curdate); } else if(year == calSys->year(first_date)) { days = calSys->daysInYear(year_date); days -= (calSys->dayOfYear(first_date) - 1); } else { days= calSys->daysInYear(year_date); } if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; double pervalue = 0.0; if(first_year) { pervalue = (((yearly_count + scheduled_count) == 0.0) ? 0.0 : ((yearly_value + scheduled_value) / (yearly_count + scheduled_count))); } else { pervalue = (yearly_count == 0.0 ? 0.0 : (yearly_value / yearly_count)); } if(enabled[5]) outf << ""; first_year = false; outf << "\n"; outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t" << '\n'; } year = calSys->year(it->date); yearly_value = it->value; yearly_count = it->count; year_date = it->date; outf << "\t\t\t\t\t"; } else { yearly_value += it->value; yearly_count += it->count; outf << "\t\t\t\t\t"; } total_value += it->value; total_count += it->count; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = 0; if(first_month) { days = calSys->day(curdate); } else if(it == it_b) { days = calSys->daysInMonth(it->date); days -= (calSys->day(first_date) - 1); } else { days = calSys->daysInMonth(it->date); } if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; double pervalue = 0.0; if(first_month) { pervalue = (((it->count + scheduled_count) == 0.0) ? 0.0 : ((it->value + scheduled_value) / (it->count + scheduled_count))); } else { pervalue = (it->count == 0.0 ? 0.0 : (it->value / it->count)); } if(enabled[5]) outf << ""; first_month = false; outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(multiple_years) { outf << "\t\t\t\t" << '\n'; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; int days = calSys->daysInYear(year_date); days -= (calSys->dayOfYear(first_date) - 1); if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; if(enabled[5]) outf << ""; outf << "\n"; outf << "\t\t\t\t" << '\n'; } if(multiple_months) { outf << "\t\t\t\t" << '\n'; int days = first_date.daysTo(curdate) + 1; outf << "\t\t\t\t\t"; outf << "\t\t\t\t\t"; if(enabled[0]) outf << ""; if(enabled[1]) outf << ""; if(enabled[2]) outf << ""; if(enabled[3]) outf << ""; if(enabled[4]) outf << ""; if(enabled[5]) outf << ""; outf << "\n"; outf << "\t\t\t\t" << '\n'; } outf << "\t\t\t" << '\n'; outf << "\t\t
" << htmlize_string(i18n("Year")) << "" << htmlize_string(i18n("Month")) << "" << htmlize_string(valuetitle); if(mi && mi->date > curdate) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(i18n("Daily Average")) << "" << htmlize_string(i18n("Monthly Average")) << "**" << "" << htmlize_string(i18n("Yearly Average")) << "**" << "" << htmlize_string(i18n("Quantity")); if(mi && mi->date > curdate) {outf << "*"; use_footer1 = true;} outf<< "" << htmlize_string(pertitle); if(mi && mi->date > curdate) {outf << "*"; use_footer1 = true;} outf<< "
" << ""; bool had_footer = false; if(use_footer1) { had_footer = true; outf << "*" << htmlize_string(i18n("Includes scheduled transactions")); } if(enabled[2] || enabled[3]) { if(had_footer) outf << "
"; outf << "**" << htmlize_string(i18n("Adjusted for the average month / year (%1 / %2 days)").arg(KGlobal::locale()->formatNumber(average_month, 1)).arg(KGlobal::locale()->formatNumber(average_year, 1))); } outf << "
" << "
" << htmlize_string(i18n("Subtotal")) << "" << htmlize_string(KGlobal::locale()->formatMoney(first_year ? (yearly_value + scheduled_value) : yearly_value)) << "" << htmlize_string(KGlobal::locale()->formatMoney(yearly_value / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney(((yearly_value * average_month) / days))) << "" << htmlize_string(KGlobal::locale()->formatMoney((yearly_value * average_year) / days)) << "" << htmlize_string(KGlobal::locale()->formatNumber(first_year ? (yearly_count + scheduled_count) : yearly_count, i_count_frac)) << "" << htmlize_string(KGlobal::locale()->formatMoney(pervalue)) << "
" << htmlize_string(calSys->yearString(it->date, false)) << "" << htmlize_string(calSys->monthName(it->date)) << "" << htmlize_string(KGlobal::locale()->formatMoney(first_month ? (it->value + scheduled_value) : it->value)) << "" << htmlize_string(KGlobal::locale()->formatMoney(it->value / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((it->value * average_month) / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((it->value * average_year) / days)) << "" << htmlize_string(KGlobal::locale()->formatNumber(first_month ? (it->count + scheduled_count) : it->count, i_count_frac)) << "" << htmlize_string(KGlobal::locale()->formatMoney(pervalue)) << "
" << htmlize_string(i18n("Subtotal")) << "" << htmlize_string(KGlobal::locale()->formatMoney(yearly_value)) << "" << htmlize_string(KGlobal::locale()->formatMoney(yearly_value / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((yearly_value * average_month) / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((yearly_value * average_year) / days)) << "" << htmlize_string(KGlobal::locale()->formatNumber(yearly_count, i_count_frac)) << "" << htmlize_string(KGlobal::locale()->formatMoney(yearly_count == 0.0 ? 0.0 : (yearly_value / yearly_count))) << "
" << htmlize_string(i18n("Total")) << "" << htmlize_string(KGlobal::locale()->formatMoney(total_value + scheduled_value)) << "" << htmlize_string(KGlobal::locale()->formatMoney(total_value / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((total_value * average_month) / days)) << "" << htmlize_string(KGlobal::locale()->formatMoney((total_value * average_year) / days)) << "" << htmlize_string(KGlobal::locale()->formatNumber(total_count + scheduled_count, i_count_frac)) << "" << htmlize_string(KGlobal::locale()->formatMoney((total_count + scheduled_count) == 0.0 ? 0.0 : ((total_value + scheduled_value) / (total_count + scheduled_count)))) << "
" << '\n'; outf << "\t" << '\n'; outf << "" << '\n'; htmlpart->begin(); htmlpart->write(source); htmlpart->end(); } void OverTimeReport::updateTransactions() { if(descriptionCombo->isEnabled() && current_account) { int curindex = 0; descriptionCombo->blockSignals(true); descriptionCombo->clear(); descriptionCombo->insertItem(i18n("All Descriptions Combined")); has_empty_description = false; QMap descriptions; Transaction *trans = budget->transactions.first(); while(trans) { if((trans->fromAccount() == current_account || trans->toAccount() == current_account)) { if(trans->description().isEmpty()) has_empty_description = true; else descriptions[trans->description()] = true; } trans = budget->transactions.next(); } QMap::iterator it_e = descriptions.end(); int i = 1; for(QMap::iterator it = descriptions.begin(); it != it_e; ++it) { if((current_source == 9 || current_source == 10) && it.key() == current_description) { curindex = i; } descriptionCombo->insertItem(it.key()); i++; } if(has_empty_description) { if((current_source == 9 || current_source == 10) && current_description.isEmpty()) curindex = i; descriptionCombo->insertItem(i18n("No description")); } if(curindex < descriptionCombo->count()) { descriptionCombo->setCurrentItem(curindex); } bool b_income = (current_account && current_account->type() == ACCOUNT_TYPE_INCOMES); if(descriptionCombo->currentItem() == 0) { if(b_income) current_source = 5; else current_source = 6; current_description = ""; } descriptionCombo->blockSignals(false); } updateDisplay(); } void OverTimeReport::updateAccounts() { if(categoryCombo->isEnabled()) { int curindex = 0; categoryCombo->blockSignals(true); descriptionCombo->blockSignals(true); categoryCombo->clear(); categoryCombo->insertItem(i18n("All Categories Combined")); int i = 1; if(sourceCombo->currentItem() == 1) { Account *account = budget->expensesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); if(account == current_account) curindex = i; account = budget->expensesAccounts.next(); i++; } } else { Account *account = budget->incomesAccounts.first(); while(account) { categoryCombo->insertItem(account->name()); if(account == current_account) curindex = i; account = budget->incomesAccounts.next(); i++; } } if(curindex < categoryCombo->count()) categoryCombo->setCurrentItem(curindex); if(curindex == 0) { descriptionCombo->clear(); descriptionCombo->setEnabled(false); descriptionCombo->insertItem(i18n("All Descriptions Combined")); if(sourceCombo->currentItem() == 2) { current_source = 1; } else { current_source = 2; } descriptionCombo->setEnabled(false); } categoryCombo->blockSignals(false); descriptionCombo->blockSignals(false); } updateDisplay(); } #include "overtimereport.moc"