Logo Search packages:      
Sourcecode: qbankmanager version File versions  Download package

summaryreport.cpp

/***************************************************************************
 $RCSfile: summaryreport.cpp,v $
                             -------------------
    cvs         : $Id: summaryreport.cpp,v 1.8 2005/09/01 07:27:38 aquamaniac Exp $
    begin       : Mon Mar 01 2004
    copyright   : (C) 2004 by Martin Preuss
    email       : martin@libchipcard.de

 ***************************************************************************
 *          Please see toplevel file COPYING for license details           *
 ***************************************************************************/



#ifdef HAVE_CONFIG_H
# include <config.h>
#endif


#include "kbanking.h"
#include "summaryreport.h"
#include "editsummaryreport.h"
#include "transfinder.h"
#include "transaction.h"
#include "account.h"

#include <gwenhywfar/waitcallback.h>

#include <qwidget.h>
#include <qstring.h>
#include <qmessagebox.h>
#include <qwidget.h>

#define I18N_NOOP(msg) msg



SummaryReport::SummaryReport(KBanking *app)
:Report(app, "SummaryReport"){


}



SummaryReport::~SummaryReport(){
}



QString SummaryReport::shortDescription(){
  return QWidget::tr("Summary reports");
}



QString SummaryReport::longDescription(){
  return QWidget::tr
    (
     "<qt>"
     "This module allows creating of summary reports."
     "</qt>"
    );
}



bool SummaryReport::initProfile(GWEN_DB_NODE *dbProfile, QWidget *parent){
  EditSummaryReport w(dbProfile, parent);

  w.setCaption(QWidget::tr("Create new profile"));
  if (w.exec()!=QDialog::Accepted)
    return false;
  return true;
}



bool SummaryReport::editProfile(GWEN_DB_NODE *dbProfile, QWidget *parent){
   EditSummaryReport w(dbProfile, parent);

  w.setCaption(QWidget::tr("Edit profile"));
  if (w.exec()!=QDialog::Accepted)
    return false;
  return true;
}



QString SummaryReport::writeRow(GWEN_DB_NODE *dbProfile,
                        const QString &dt,
                        const AB_VALUE *vIncome,
                        const AB_VALUE *vExpense,
                        const AB_VALUE *vBalance,
                                const AB_VALUE *vBalanceSum,
                        bool fat) {
  QString qs;
  char numbuf[32];

  /* create row string */
  qs+="<tr>";

  /* date */
  qs+="<td>";
  if (fat)
    qs+="<b>";
  qs+=dt;
  if (fat)
    qs+="</b>";
  qs+="</td>";

  /* income */
  if (GWEN_DB_GetIntValue(dbProfile, "showIncome", 0, 1)) {
    qs+="<td align=\"right\">";
    if (fat)
      qs+="<b>";
#if !defined(__GNUC__) && defined(WIN32)
    // This is MSVC compiler which doesnt have snprintf()
    sprintf(numbuf, "%.2lf", AB_Value_GetValue(vIncome));
#else
    snprintf(numbuf, sizeof(numbuf), "%.2lf", AB_Value_GetValue(vIncome));
#endif
    qs+=numbuf;
    qs+=" ";
    qs+=AB_Value_GetCurrency(vIncome);
    if (fat)
      qs+="</b>";
    qs+="</td>";
  }

  /* expense */
  if (GWEN_DB_GetIntValue(dbProfile, "showExpense", 0, 1)) {
    qs+="<td align=\"right\">";
    if (fat)
      qs+="<b>";
#if !defined(__GNUC__) && defined(WIN32)
    // This is MSVC compiler which doesnt have snprintf()
    sprintf(numbuf, "%.2lf", AB_Value_GetValue(vExpense));
#else
    snprintf(numbuf, sizeof(numbuf), "%.2lf", AB_Value_GetValue(vExpense));
#endif
    qs+=numbuf;
    qs+=" ";
    qs+=AB_Value_GetCurrency(vExpense);
    if (fat)
      qs+="</b>";
    qs+="</td>";
  }

  /* balance */
  if (GWEN_DB_GetIntValue(dbProfile, "showBalance", 0, 1)) {
    qs+="<td align=\"right\">";
    if (fat)
      qs+="<b>";
    if (GWEN_DB_GetIntValue(dbProfile, "useColours", 0, 0)) {
      if (AB_Value_GetValue(vBalance)>0)
        qs+="<font color=\"dark green\">";
      else
        qs+="<font color=red>";
    }
#if !defined(__GNUC__) && defined(WIN32)
    // This is MSVC compiler which doesnt have snprintf()
    sprintf(numbuf, "%.2lf", AB_Value_GetValue(vBalance));
#else
    snprintf(numbuf, sizeof(numbuf), "%.2lf", AB_Value_GetValue(vBalance));
#endif
    qs+=numbuf;
    qs+=" ";
    qs+=AB_Value_GetCurrency(vBalance);
    if (GWEN_DB_GetIntValue(dbProfile, "useColours", 0, 0))
      qs+="</font>";
    if (fat)
      qs+="</b>";
    qs+="</td>";
  }

  /* balance sum */
  if (GWEN_DB_GetIntValue(dbProfile, "showSummedBalance", 0, 1)) {
    qs+="<td align=\"right\">";
    if (vBalanceSum) {
      if (fat)
        qs+="<b>";
      if (GWEN_DB_GetIntValue(dbProfile, "useColours", 0, 0)) {
        if (AB_Value_GetValue(vBalanceSum)>0)
          qs+="<font color=\"dark green\">";
        else
          qs+="<font color=red>";
      }
#if !defined(__GNUC__) && defined(WIN32)
      // This is MSVC compiler which doesnt have snprintf()
      sprintf(numbuf, "%.2lf", AB_Value_GetValue(vBalanceSum));
#else
      snprintf(numbuf, sizeof(numbuf), "%.2lf", AB_Value_GetValue(vBalanceSum));
#endif
      qs+=numbuf;
      qs+=" ";
      qs+=AB_Value_GetCurrency(vBalanceSum);
      if (GWEN_DB_GetIntValue(dbProfile, "useColours", 0, 0))
        qs+="</font>";
      if (fat)
        qs+="</b>";
    }
    qs+="</td>";
  }

  qs+="</tr>\n";

  return qs;
}




QString SummaryReport::handleDay(GWEN_DB_NODE *dbProfile,
                         QWidget *parent,
                         Report::Day *dy,
                         AB_VALUE *vMonthIncome,
                                 AB_VALUE *vMonthExpense,
                                 AB_VALUE *vBalanceSum,
                                 bool drawAlso) {
  std::list<RefPointer<Transaction> >::iterator it;
  AB_VALUE *vIncome;
  AB_VALUE *vExpense;
  AB_VALUE *vBalance;
  QString qs;

  /* add values */
  vIncome=AB_Value_new(0, 0);
  vExpense=AB_Value_new(0, 0);
  for (it=dy->transactions().begin(); it!=dy->transactions().end(); it++) {
    const AB_VALUE *vConst;

    vConst=(*it).ref().getValue();
    if (vConst) {
      if (AB_Value_IsNegative(vConst)) {
      AB_VALUE *vTemp;

      vTemp=AB_Value_dup(vConst);
        AB_Value_Negate(vTemp);
      AB_Value_AddValue(vExpense, vTemp);
      AB_Value_AddValue(vMonthExpense, vTemp);
        AB_Value_free(vTemp);
      }
      else {
      AB_Value_AddValue(vIncome, vConst);
      AB_Value_AddValue(vMonthIncome, vConst);
      }
    }
  } /* for */

  /* calculate balance */
  vBalance=AB_Value_dup(vIncome);
  AB_Value_SubValue(vBalance, vExpense);

  AB_Value_AddValue(vBalanceSum, vBalance);

  if (drawAlso) {
    GWEN_TIME *ti;
    GWEN_BUFFER *tbuf;

    ti=GWEN_Time_new(dy->getYear(),
                     dy->getMonth(),
                     dy->getDay(),
                     12, 0, 0, 1);
    assert(ti);
    tbuf=GWEN_Buffer_new(0, 32, 0, 1);
    GWEN_Time_toString(ti,
                       KBanking::QStringToUtf8String(tr("YYYY/MM/DD")).c_str(),
                       tbuf);
    GWEN_Time_free(ti);

    qs=writeRow(dbProfile,
                QString::fromUtf8(GWEN_Buffer_GetStart(tbuf)),
                vIncome,
                vExpense,
                vBalance,
                vBalanceSum,
                false);

    GWEN_Buffer_free(tbuf);
  }

  /* cleanup */
  AB_Value_free(vBalance);
  AB_Value_free(vExpense);
  AB_Value_free(vIncome);

  return qs;
}



QString SummaryReport::handleMonth(GWEN_DB_NODE *dbProfile,
                           QWidget *parent,
                           Report::Month *m,
                                   AB_VALUE *vAccountIncome,
                                   AB_VALUE *vAccountExpense,
                                   AB_VALUE *vAccountBalanceSum) {
  QString qs;
  std::list<RefPointer<Transaction> > tl;
  std::list<Report::Day*>::iterator it;
  AB_VALUE *vIncome;
  AB_VALUE *vExpense;
  AB_VALUE *vBalance;
  bool showDays;
  QString ts;
  const char *monthNames[12]={
    I18N_NOOP("January"), I18N_NOOP("February"), I18N_NOOP("March"),
    I18N_NOOP("April"), I18N_NOOP("May"), I18N_NOOP("June"),
    I18N_NOOP("July"), I18N_NOOP("August"), I18N_NOOP("September"),
    I18N_NOOP("October"), I18N_NOOP("November"), I18N_NOOP("December")};

  showDays=GWEN_DB_GetIntValue(dbProfile, "showDays", 0, 1);
  if (showDays) {
    qs+=tr("<h3>Overview for %1 %2</h3>\n")
      .arg(tr(monthNames[m->getMonth()]))
      .arg(m->getYear());

    if (GWEN_DB_GetIntValue(dbProfile, "border", 0, 0))
      qs+=tr("<table border=\"1\">\n");
    else
      qs+=tr("<table>\n");
    qs+="<tr>";

    qs+="<th align=\"center\">";
    qs+=tr("Date");
    qs+="</th>";

    if (GWEN_DB_GetIntValue(dbProfile, "showIncome", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Income");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showExpense", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Expense");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showBalance", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Balance");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showSummedBalance", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Cumulative Balance");
      qs+="</th>";
    }

    qs+="</tr>\n";
  }

  // handle days
  sortDays(m->days());
  vIncome=AB_Value_new(0, 0);
  vExpense=AB_Value_new(0, 0);
  for (it=m->days().begin(); it!=m->days().end(); it++) {
    qs+=handleDay(dbProfile, parent, *it, vIncome, vExpense,
                  vAccountBalanceSum,
                  showDays);
  }

  /* calculate balance */
  vBalance=AB_Value_dup(vIncome);
  AB_Value_SubValue(vBalance, vExpense);

  if (showDays)
    ts=tr("Summary");
  else
    ts=tr("%1 %2")
      .arg(tr(monthNames[m->getMonth()]))
      .arg(m->getYear());

  qs+=writeRow(dbProfile,
               ts,
               vIncome,
               vExpense,
               vBalance,
               vAccountBalanceSum,
               showDays?true:false);

  AB_Value_AddValue(vAccountIncome, vIncome);
  AB_Value_AddValue(vAccountExpense, vExpense);

  /* cleanup */
  AB_Value_free(vBalance);
  AB_Value_free(vExpense);
  AB_Value_free(vIncome);

  if (showDays)
    qs+="</table>";

  return qs;
}



QString SummaryReport::handleAccount(GWEN_DB_NODE *dbProfile,
                             QWidget *parent,
                             Report::AccountData *ad){
  Account *a=0;
  std::string bankName;
  std::string accountName;
  QString qs;
  std::list<Year*>::iterator yit;
  std::list<RefPointer<Transaction> >::iterator it;
  AB_VALUE *vIncome;
  AB_VALUE *vExpense;
  AB_VALUE *vBalanceSum;
  const AB_VALUE *vRealBalance=0;
  bool showDays;
  bool mixAccounts;
  bool calcRealBalance;

  showDays=GWEN_DB_GetIntValue(dbProfile, "showDays", 0, 1);
  mixAccounts=GWEN_DB_GetIntValue(dbProfile, "mixAccounts", 0, 0);
  calcRealBalance=GWEN_DB_GetIntValue(dbProfile, "calcRealBalance", 0, 0);

  if (mixAccounts) {
    qs=tr("<h2>Summary Report</h2>\n");
  }
  else {
    const AB_ACCOUNT_STATUS *ast;

    a=ad->getAccount();
    if (GWEN_DB_GetIntValue(dbProfile, "useAccountName", 0, 0)) {
      if (!(a->getAccountName().empty()))
        accountName=a->getAccountName();
    }
    if (GWEN_DB_GetIntValue(dbProfile, "useBankName", 0, 0)) {
      if (!(a->getBankName().empty()))
        bankName=a->getBankName();
    }

    qs=tr("<h2>Summary Report for Account <i>%1</i> at <i>%2</i> </h2>\n")
      .arg(accountName.c_str())
      .arg(bankName.c_str());

    ast=a->getAccountStatus();
    if (ast) {
      const AB_BALANCE *bb;

      bb=AB_AccountStatus_GetBookedBalance(ast);
      if (!bb)
        bb=AB_AccountStatus_GetNotedBalance(ast);
      if (bb) {
        const GWEN_TIME *ti;

        ti=AB_Balance_GetTime(bb);
        if (ti) {
          const AB_VALUE *val;

          val=AB_Balance_GetValue(bb);
          if (val) {
            if (GWEN_DB_GetIntValue(dbProfile, "showBalance", 0, 0)) {
              GWEN_BUFFER *tbuf;
              const char *currency;

              // now we have all we need for a balance statement
              currency=AB_Value_GetCurrency(val);
              if (!currency)
                currency="EUR";
              tbuf=GWEN_Buffer_new(0, 32, 0, 1);
              GWEN_Time_toString(ti,
                                 tr("YYYY/MM/DD (hh:mm)").latin1(),
                                 tbuf);
              qs+=tr("<b>Account balance</b> on %1: %2 %3<br>\n")
                .arg(GWEN_Buffer_GetStart(tbuf))
                .arg(AB_Value_GetValue(val), 10, 'f', 2)
                .arg(currency);
            } // if showBalance
            vRealBalance=val;
          }
        }
      } // if bookedBalance
    } // if accountStatus
  } // if !mixAccounts

  qs+="<br>";

  if (!showDays) {
    if (GWEN_DB_GetIntValue(dbProfile, "border", 0, 0))
      qs+=tr("<table border=\"1\">\n");
    else
      qs+=tr("<table>\n");
    qs+="<tr>";

    qs+="<th align=\"center\">";
    qs+=tr("Date");
    qs+="</th>";

    if (GWEN_DB_GetIntValue(dbProfile, "showIncome", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Income");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showExpense", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Expense");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showBalance", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Balance");
      qs+="</th>";
    }

    if (GWEN_DB_GetIntValue(dbProfile, "showSummedBalance", 0, 1)) {
      qs+="<th align=\"center\">";
      qs+=tr("Cumulative Balance");
      qs+="</th>";
    }

    qs+="</tr>\n";
  }

  sortYears(ad->years());

  vIncome=AB_Value_new(0, 0);
  vExpense=AB_Value_new(0, 0);
  vBalanceSum=AB_Value_new(0, 0);

  if (vRealBalance && calcRealBalance) {
    AB_VALUE *vDiff;

    /* insert a walk to calculate the offset */
    vIncome=AB_Value_new(0, 0);
    vExpense=AB_Value_new(0, 0);
    vBalanceSum=AB_Value_new(0, 0);

    for (yit=ad->years().begin();
         yit!=ad->years().end();
         yit++) {
      std::list<Month*>::iterator mit;

      sortMonths((*yit)->months());
      for (mit=(*yit)->months().begin();
           mit!=(*yit)->months().end();
           mit++) {
        /* ignore created string here */
        handleMonth(dbProfile, parent, *mit, vIncome, vExpense,
                    vBalanceSum);
      }
    } // for
    vDiff=AB_Value_dup(vRealBalance);
    AB_Value_SubValue(vDiff, vBalanceSum);
    AB_Value_free(vBalanceSum);
    vBalanceSum=vDiff;

    /* reset working values */
    AB_Value_free(vExpense);
    AB_Value_free(vIncome);
    vIncome=AB_Value_new(0, 0);
    vExpense=AB_Value_new(0, 0);
  }

  for (yit=ad->years().begin();
       yit!=ad->years().end();
       yit++) {
    std::list<Month*>::iterator mit;

    sortMonths((*yit)->months());
    for (mit=(*yit)->months().begin();
         mit!=(*yit)->months().end();
         mit++) {
      qs+=handleMonth(dbProfile, parent, *mit, vIncome, vExpense,
                      vBalanceSum);
    }
  } // for


  if (!showDays) {
    AB_VALUE *vBalance;

    /* calculate balance */
    vBalance=AB_Value_dup(vIncome);
    AB_Value_SubValue(vBalance, vExpense);

    qs+=writeRow(dbProfile,
                 tr("Summary"),
                 vIncome,
                 vExpense,
                 vBalance,
                 vBalanceSum,
                 true);
    AB_Value_free(vBalance);
    qs+=tr("</table>\n");
  }

  /* cleanup */
  AB_Value_free(vBalanceSum);
  AB_Value_free(vExpense);
  AB_Value_free(vIncome);


  return qs;
}



bool SummaryReport::useProfile(GWEN_DB_NODE *dbProfile, QWidget *parent){
  QString qs;
  std::list<RefPointer<Transaction> > tl;
  std::list<RefPointer<Transaction> >::iterator it;
  std::list<AccountData*> adl;
  std::list<AccountData*>::iterator ait;
  RefPointer<Transaction> t;
  bool mixAccounts;

  if (!TransactionFinder::selectTransactions(app(), &tl,
                                             tr("Select Transactions"),
                                             TRANSFINDER_FLAGS_USE_CATEGORY |
                                             TRANSFINDER_FLAGS_EXT_PAYEES,
                                             parent)) {
    DBG_ERROR(0, "Transaction finder aborted");
    return false;
  }

  if (tl.empty()) {
    DBG_ERROR(0, "No transactions");
    return false;
  }
  t=tl.front();

  mixAccounts=GWEN_DB_GetIntValue(dbProfile, "mixAccounts", 0, 0);

  for (it=tl.begin(); it!=tl.end(); it++) {
    DBG_ERROR(0, "Adding Transaction");
    addTransaction(adl, *it, mixAccounts);
  } // for


  qs=tr("<html>");

  for (ait=adl.begin(); ait!=adl.end(); ait++) {
    qs+="<page>";
    DBG_ERROR(0, "Handling account");
    qs+=handleAccount(dbProfile, parent, *ait);
    qs+="</page>";
  } // for

  qs+=tr("</html>");

  AB_Banking_Print(app()->getCInterface(),
                   KBanking::QStringToUtf8String(tr("Summary Report")).c_str(),
                   "REPORT:SUMMARYREPORT",
                   KBanking::QStringToUtf8String(shortDescription()).c_str(),
                   KBanking::QStringToUtf8String(qs).c_str());

  return true;
}




















Generated by  Doxygen 1.6.0   Back to index