Subversion Repositories public

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

/***************************************************************************
 *   Copyright (C) 2007 by Andreas Theofilu   *
 *   andreas@TheoSys.at   *
 *                                                                         *
 *   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.             *
 ***************************************************************************/


#include "helper.h"
#include "tprech.h"
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include <kmessagebox.h>
#include <qstring.h>
#include <qfile.h>
#include <qdir.h>

// #include <iostream.h>

char AbschlPlan[12];
int MonLeiste[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
                 /*  Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez */;

/***************************************************************************
 * TILGPL: Modul zur Berechnung eines Tilgungsplans                        *
 *         Die errechneten Daten werden in einer Datei zwischengespeichert *
 *         und können so auf jede beliebige Art ausgegeben werden.         *
 ***************************************************************************/

int TRech::tilgpl ()
{
int fd, day, mon, year, akt_mon, index, akt_day, akt_year, i, j, a;
int vday, at, am, aj, zwat;
long tage, pos, ldat, r_dat, a_dat, tg, lab, t1, t2;
long tg_per;
double zins, tilg, zi1, zi2, kzi, sumrat;
long offset;
char buf[255];
BOOL abschluss, r_yet;

        init_global_vars ();
        rund_fakt = (TpPars->runden) ? 0 : 2;
        date_int (&day, &mon, &year, TpPars->dvon);

        if (TpPars->ultimo)              /* Wenn Ultimo Datum korrigieren */
        {
           set_feb (year);
           day = MonLeiste[mon-1];
           TpPars->dvon = make_date (day, mon, year);
        }

/* Überprüfen der Daten */

        if (TpPars->dvon == 0L)
           return 2;

        if (TpPars->ragab <= 0L)
           return 8;

        if (DateToDay (TpPars->ragab) > DateToDay (TpPars->dvon))
           return 3;

        if (TpPars->abschlry != 1 && TpPars->abschlry != 3 && TpPars->abschlry != 6 &&
            TpPars->abschlry != 12 && TpPars->abschlry != 41 && TpPars->abschlry != 43 &&
            TpPars->abschlry != 46 && TpPars->abschlry != 47 && TpPars->abschlry != 48 &&
            TpPars->abschlry != 52)
           return 11;

        if (TpPars->abschlry > 40)
           TpPars->abschl = 0L;

        if (TpPars->abschl > 0L && DateToDay (TpPars->abschl) < DateToDay (TpPars->ragab))
           return 4;

        // Abschlußplan erstellen

        for (i = 0; i < 12; i++)
           AbschlPlan[i] = 0;

        switch (TpPars->abschlry)
        {
           case  1:
           case 41: for (i = 0; i < 12; i++)
                       AbschlPlan[i] = 1;
           break;

           case  3:
           case 43: AbschlPlan[2] = 1;
                    AbschlPlan[5] = 1;
                    AbschlPlan[8] = 1;
                    AbschlPlan[11] = 1;
           break;

           case  6:
           case 46: AbschlPlan[5] = 1;
                    AbschlPlan[11] = 1;
           break;

           case 12:
           case 52: AbschlPlan[11] = 1;
           break;

           case 47: AbschlPlan[2] = 1;
                    AbschlPlan[8] = 1;
           break;

           case 48: AbschlPlan[1] = 1;
                    AbschlPlan[7] = 1;
           break;
        }

        if (TpPars->fixrate == TRUE)
        {
           if (TpPars->rate < 0.0)
              return 16;
           else if (TpPars->rate == 0.0)
              return 15;

           TpPars->dbis = 0L;
        }
        else
           TpPars->rate = 0.0;

        if (TpPars->dbis > 0L)
        {
           date_int (&i, &akt_mon, &akt_year, TpPars->dvon);
           date_int (&day, &akt_mon, &akt_year, TpPars->dbis);
           set_feb (akt_year);

           if (i > MonLeiste[akt_mon-1])
              i = MonLeiste[akt_mon-1];

           TpPars->dbis = make_date (i, akt_mon, akt_year);
        }

        if (TpPars->dbis > 0L && DateToDay (TpPars->dvon) > DateToDay (TpPars->dbis))
           return 5;

        if (TpPars->endfaell > 0L && DateToDay (TpPars->dbis) > DateToDay (TpPars->endfaell))
           return 6;

        i = j = 0;

        while (i < 12)
        {
           if (TpPars->raplan[i] > 0)
           {
              j = 1;
              break;
           }

           i++;
        }

        if (!j)
           return 7;

        date_int (&day, &mon, &year, TpPars->dvon);

        if (TpPars->raplan[mon-1] <= 0)
           return 18;           // Ungültiges Datum "Von"

        if (!TpPars->fixrate)
        {
           date_int (&day, &mon, &year, TpPars->dbis);

           if (TpPars->raplan[mon-1] <= 0)
              return 19;                // Ungültiges Datum "Bis"
        }

        if (TpPars->verzart == 1 && TpPars->abschlry != 43 && TpPars->abschlry != 46 &&
            TpPars->abschlry != 52)
           return 9;

        if (TpPars->abschl == 0L && TpPars->abschlry < 41)
           return 10;

/* Verzinsung */

        if (TpPars->verzart == 0 || TpPars->verzart == 2 || TpPars->verzart == 8)
           verzinsung = 0;
        else if (TpPars->verzart == 3)
           verzinsung = 1;
        else if (TpPars->verzart == 7)
           verzinsung = 2;
        else if (TpPars->verzart == 4)
           verzinsung = 3;
        else
           return 12;

/* Ratenart */

        if (TpPars->ratenart < 0 || TpPars->ratenart > 3)
           return 13;

        if (TpPars->ratenart == 0)
           reh = 1;
        else if (TpPars->ratenart == 1)
           reh = 2;
        else
           reh = 0;

/* Divisor: */

        if (TpPars->tageb == 1 || TpPars->tageb == 2 || TpPars->tageb == 7 || TpPars->tageb == 8)
           divisor = 36000.0;
        else
           divisor = 36500.0;

/* Berechnung der Laufzeit, Abschlußdaten und   */
/* Erstellen einer Datumstabelle */

        if (TpPars->fixrate == TRUE && TpPars->endfaell > 0L)
           TpPars->dbis = TpPars->endfaell;

        if (TpPars->dbis == 0L)
        {
           tage = (99L * 365L) + (99L / 4L);          /* 99 Jahre = Maximallaufzeit */
           TpPars->dbis = DayToDate (tage + DateToDay (TpPars->ragab));
        }

        if (TpPars->ultimo)
        {
           if (TpPars->verzart == 3 || TpPars->verzart == 7)
              day = 1;
           else
           {
              date_int (&day, &mon, &year, TpPars->dbis);
              day = MonLeiste[mon-1];
              TpPars->dbis = make_date (day, mon, year);
           }
        }
        else if (verzinsung == 1 || verzinsung == 2)    /* Antizipativ */
        {
           date_int (&day, &mon, &year, TpPars->dbis);
           day = 1;
           TpPars->dbis = make_date (day, mon, year);
        }

        if (TpPars->endfaell > 0L)
           tage = DateToDay (TpPars->endfaell) - DateToDay (TpPars->ragab);
        else
           tage = DateToDay (TpPars->dbis) - DateToDay (TpPars->ragab);

        if (tage > 36525L)
           return 14;           /* Laufzeit über 100 Jahre!! */

        if (TpPars->abschl == 0L)
           TpPars->abschl = TpPars->ragab;

        date_int (&vday, &mon, &year, TpPars->dvon);
        date_int (&day, &mon, &year, TpPars->ragab);
        date_int (&at, &am, &aj, TpPars->abschl);
        akt_mon = mon - 1;
        a_ind = r_ind = 0;
        pos = 0;
        abschluss = FALSE;
        r_yet = FALSE;          /* Nur TRUE wenn "a_dat" < TpPars->dvon */
        lab = 0L;

        while (pos < tage)
        {
           set_feb (year);

           /* Abschlußdatum */

           if (TpPars->abschlry > 40)
              akt_day = MonLeiste[akt_mon];
           else
           {
              if (at > MonLeiste[akt_mon])
                 akt_day = MonLeiste[akt_mon];
              else
                 akt_day = at;
           }

           a_dat = make_date (akt_day, akt_mon+1, year);

           if (!abschluss && (verzinsung == 1 || verzinsung == 2))      /* Antizipativ */
           {
              ab_dat[a_ind] = TpPars->ragab;
              lab = TpPars->ragab;

              if (!abschluss)
              {
                 TpPars->abschl = TpPars->ragab;
                 abschluss = TRUE;
              }

              a_ind++;
           }
           else if ((verzinsung == 1 || verzinsung == 2) &&     /* Antizipativ */
                    test_abschl (akt_mon+1) && a_dat < TpPars->dbis)
           {
              a_dat = DateToDay (a_dat);
              a_dat = DayToDate (a_dat + 1L);
              ab_dat[a_ind] = a_dat;
              lab = a_dat;

              if (!abschluss)
              {
                 TpPars->abschl = TpPars->ragab;
                 abschluss = TRUE;
              }

              a_ind++;
           }
           else if (test_abschl (akt_mon+1) &&          /* Dekursiv */
                    verzinsung != 1 && verzinsung != 2 &&
                    AbschlPlan[akt_mon] && a_dat > TpPars->ragab)
           {
              ab_dat[a_ind] = a_dat;
              lab = a_dat;

              if (a_dat < TpPars->dvon)
                 r_yet = TRUE;

              if (!abschluss)
              {
                 TpPars->abschl = TpPars->ragab;
                 abschluss = TRUE;
              }

              a_ind++;
           }

           /* Einschränkungsdatum */

           if (TpPars->ultimo == TRUE)
              akt_day = MonLeiste[akt_mon];
           else
           {
              if (vday > MonLeiste[akt_mon])
                 akt_day = MonLeiste[akt_mon];
              else
                 akt_day = vday;
           }

           r_dat = make_date (akt_day, akt_mon+1, year);

           if ((TpPars->raplan[akt_mon] && r_dat >= TpPars->dvon &&
               r_dat <= TpPars->dbis) || r_yet)
           {
              rat_dat[r_ind] = r_dat;
              ldat = r_dat;
              rat_anz[r_ind] = TpPars->raplan[akt_mon];
              r_ind++;
              r_yet = FALSE;
           }

           akt_mon++;

           if (akt_mon >= 12)
           {
              akt_mon = 0;
              year++;
           }

           pos = DateToDay (r_dat) - DateToDay (TpPars->ragab);
        }

        if (lab != a_dat)
        {
           ab_dat[a_ind] = TpPars->dbis;
           a_ind++;
        }

        TpPars->dbis = ldat;
        max_abs = a_ind;
        max_rat = r_ind;

/* Start der Berechnungen
        Ratenberechnung */

        a_ind = r_ind = 0;

        if (TpPars->fixrate == TRUE)    // Besteht eine Ratenvorgabe?
        {
           TpPars->ergrate = rat = TpPars->rate;
           return gesamt1 ();
        }

/*      if (rat_dat[r_ind] < TpPars->dvon)
           while (rat_dat[r_ind] <= ab_dat[a_ind])
              r_ind++;
*/
        if (rat_dat[r_ind] < TpPars->dvon)
           while (rat_dat[r_ind] < TpPars->dvon)
              r_ind++;

        dat_par = TpPars->ragab;
        tageber (dat_par);
        kap = TpPars->rahmen;
        rat = 0.0;
        ab_tag = tg_par;
        vorrech ();

        while (r_ind < max_rat && a_ind < max_abs)
        {
           if (rat_dat[r_ind] > ab_dat[a_ind])
           {
              abschlus ();
              vorrech ();
           }
           else if (rat_dat[r_ind] < ab_dat[a_ind])
              einschr ();
           else if (verzinsung == 1 || verzinsung == 2)
           {
              abschlus ();
              vorrech ();
              einschr ();
           }
           else
           {
              einschr ();
              abschlus ();
              vorrech ();
           }
        }

        if (verzinsung == 1 || verzinsung == 2)
        {
           abschlus ();
           einschr ();
        }
        else
        {
           einschr ();
           abschlus ();
        }

        if (rat != 0.0)
        {
           rat = (kap - TpPars->kapital) / rat;
           TpPars->ergrate = runden (rat, rund_fakt);

           if (TpPars->ergrate != rat && rund_fakt > 0)
              rat = TpPars->ergrate + (1.0 / pow (10.0, (double)rund_fakt));
           else if (rund_fakt == 0 && TpPars->ergrate != rat)
              rat = TpPars->ergrate + 1.0;
        }

        TpPars->ergrate = rat;
        return gesamt1 ();
}

/************************************************************************
   Erstellung eines Tilgungsplans.

   Dieser wird in eine Datei ausgegeben. Die Datei besteht aus einem
   Kopf (Übergabestruktur) und einzelnen Datensätzen.
*************************************************************************/

int TRech::gesamt1 ()
{
QString hdir = QDir::homeDirPath ();
QFile tmpFile;
int fd, day, mon, year, akt_mon, index, akt_day, akt_year, i, j, a;
int vday, at, am, aj, zwat, real_rat, Abzug;
long tage, pos, ldat, r_dat, a_dat, tg, lab, t1, t2;
long tg_per;
double zins, tilg, zi1, zi2, kzi, sumrat;
long offset, loff;
char buf[255];
BOOL stop;
DTABLE old_tab;

        /* Planerstellung */
        hdir.append("/.date_tbl.dat");
        tmpFile.setName(hdir);

        if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
        {
           KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
           return 1;
        }
        
//      if ((fd = open ("~/.date_tbl.dat", O_RDWR | O_CREAT | O_TRUNC, 0644)) == -1)
//         return 1;           /* keine Temporärdatei */
        fd = tmpFile.handle();
        offset = 0L;

        if (verzinsung == 1 || verzinsung == 2)
           index = max_abs - 1 + max_rat;
        else
           index = max_abs + max_rat;

        /* Ausgangsdaten schreiben */
        write (fd, &TpPars, sizeof (TPPARS));
        tmpFile.flush();
        offset += (long)sizeof (TPPARS);

        /* Initialisierung der Schleife */

        a_ind = r_ind = 0;
        kap = TpPars->rahmen;
        zins = 0.0;
        TpPars->gesamt = kap;
        tilg = kzi = 0.0;
        tg = 0;
        TpPars->abschl = ab_dat[0];
        stop = FALSE;                   // TRUE wenn Laufzeitende bei Ratenvorgabe
        real_rat = max_rat;
        Abzug = 0;                      // wird nur bei Ratenvorgabe verwendet

        /* Schleife zur Berechnung der Gesamtbelastung (Dekursiv) */
        
        if (verzinsung != 1 && verzinsung != 2)
        {
           for (i = 0; i < index; i++)
           {
              if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
              {
                 DTable.datum = rat_dat[r_ind];
                 DTable.kz = 'R';
                 DTable.kapital = runden (kap, rund_fakt);

                 if (r_ind > 0)
                 {
                    if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
                       ldat = ab_dat[a_ind-1];
                    else
                       ldat = rat_dat[r_ind-1];

//                  if (a_ind > 0 && ab_dat[a_ind-1] < rat_dat[r_ind])
//                     tg = tageber (rat_dat[r_ind]) - tageber (ab_dat[a_ind-1]);
//                  else
//                     tg = tageber (rat_dat[r_ind]) - tageber (rat_dat[r_ind-1]);
                    tg = tageber (rat_dat[r_ind]) - tageber (ldat);
                 }
                 else
                    tg = tageber (rat_dat[r_ind]) - tageber (TpPars->ragab);

                 zi1 = kap * (double)tg * TpPars->zssoll / divisor;
                 zins += zi1;
                 kzi += runden (zi1, rund_fakt);
                 zins = runden (zins, rund_fakt);

                 if (TpPars->fixrate == TRUE)   /* Ratenvorgabe */
                 {
                    if (!stop && r_ind > 0 && DTable.rkapi < rat)
                    {
                       max_rat = r_ind + 1;
                       max_abs = a_ind + 1;
                       real_rat = max_rat - Abzug;
                       ab_dat[a_ind] = rat_dat[r_ind];
                       index = max_rat + max_abs;
                       stop = TRUE;
                    }
                 }

                 if (r_ind == (max_rat - 1))            /* letzte Rate */
                 {
                    if (reh != 1)
                       zi2 = rat + ((TpPars->gesamt + zins) - (rat * (double)real_rat));
                    else
                       zi2 = rat - ((rat * (double)real_rat) - TpPars->rahmen);

                    rat = zi2 + TpPars->spesen;
                 }

                 TpPars->lrate = rat;
                 tilg += rat;                           /* Tilgung */

                 if (DTable.datum >= TpPars->dvon)      /* Restkapital */
                    kap -= rat;

                 DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
                 DTable.tilg = 0.0;
                 DTable.rate = rat;
                 DTable.zinsen = zi1;
                 r_ind++;
              }
              else
              {
                 DTable.datum = ab_dat[a_ind];
                 DTable.kz = 'A';

                 if (r_ind > 0 && rat_dat[r_ind-1] <= ab_dat[0])
                    DTable.kapital = TpPars->rahmen;
                 else
                    DTable.kapital = (kap >= 0.0) ? kap : 0.0;

                 kap += TpPars->spesen;
                 DTable.rate = 0.0;

                 if (r_ind > 0)
                 {
                    if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
                       ldat = ab_dat[a_ind-1];
                    else
                       ldat = rat_dat[r_ind-1];

                    tg = tageber (ab_dat[a_ind]) - tageber (ldat);

                    if (tg > 0)
                    {
                       zi1 = kap * (double)tg * TpPars->zssoll / divisor;
                       zins += zi1;
                       kzi += runden (zi1, rund_fakt);
                       zins = runden (zins, rund_fakt);
                    }
                 }

                 DTable.zinsen = zins;
                 TpPars->gesamt += zins + TpPars->spesen;       /* Gesamtbelastung */

                 if (reh != 2)
                    tilg -= zins;               /* Tilgung - Zinsen */

                 if (DTable.datum < TpPars->dvon)
                    DTable.tilg = 0.0;
                 else
                    DTable.tilg = tilg;

                 if (reh != 1)
                    kap += zins;

                 DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
                 zins = 0.0;
                 tilg = 0.0;
                 a_ind++;
              } /* end if */

/*            if (DTable.datum <= ab_dat[0] && DTable.datum < TpPars->dvon &&
                  DTable.kz == 'R') */
              if (DTable.datum < TpPars->dvon && DTable.kz == 'R')
              {
                 if (TpPars->fixrate)
                    Abzug++;
                 else
                    real_rat--;

                 continue;
              }

              write (fd, &DTable, sizeof (DTABLE));
              offset += (long)sizeof (DTABLE);
           } /* end for */
        } /* end if "Dekursiv" */

        if (verzinsung == 1 || verzinsung == 2) /* Gesamtbelastung Antizipativ */
        {
           a_ind++;                     /* Start bei 1! */
           ab_tag = tageber (ab_dat[a_ind]);
           tageber (TpPars->ragab);
           tg_alt = tg_par;
           sumrat = 0.0;
           DTable.rkapi = runden (kap, rund_fakt);
           DTable.kapital = runden (kap, rund_fakt);
           loff = offset;
           old_tab.datum = ab_dat[0];
           old_tab.kz = 'A';
           old_tab.kapital = TpPars->rahmen;
           write (fd, &old_tab, sizeof (DTABLE));       /* Platzhalter */
           offset += (long)sizeof (DTABLE);

           for (i = 0; i < index-1; i++)
           {
              if ((rat_dat[r_ind] < ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
              {
                 DTable.datum = rat_dat[r_ind];
                 DTable.kz = 'R';

                 tageber (rat_dat[r_ind+1]);
                 t1 = ab_tag - tg_alt;
                 t2 = ab_tag - tg_par;

                 if (rat > (DTable.rkapi - TpPars->kapital))
                    rat = runden (DTable.rkapi - TpPars->kapital, rund_fakt);

                 sumrat += rat;
                 kap -= rat;

                 if (verzinsung == 1)
                 {
                    kzi = kap * TpPars->zssoll * ((double)t1 *
                          (divisor - (double)t2 * TpPars->zssoll) -
                          (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
                          ((divisor - (double)t1 * TpPars->zssoll) *
                          (divisor - (double)t2 * TpPars->zssoll));
                 }
                 else
                    kzi = kap * (tg_par - tg_alt) * TpPars->zssoll / divisor;

                 kzi = runden (kzi, rund_fakt);
                 tg_alt = tg_par;
                 zins += kzi;
                 DTable.rkapi = DTable.kapital + zins - sumrat;

                 if (TpPars->fixrate == TRUE)   /* Ratenvorgabe */
                 {
                    if (!stop && r_ind > 0 && DTable.rkapi < rat)
                    {
                       max_rat = r_ind + 1;
                       max_abs = a_ind + 1;
                       ab_dat[a_ind] = rat_dat[r_ind];
                       real_rat = max_rat - Abzug;
                       index = max_rat + max_abs;
                       stop = TRUE;
                    }
                 }

                 DTable.tilg = rat - kzi;
                 tilg += DTable.tilg;
                 TpPars->lrate = rat;

                 DTable.rate = rat;
                 DTable.zinsen = kzi;
                 r_ind++;
              }
              else                      /* Abschluß */
              {
                 DTable.datum = ab_dat[a_ind];

                 if (i == (index-2))
                 {
                    DTable.kz = 'R';
                    max_rat++;
                    TpPars->lrate = DTable.kapital - tilg;
                 }
                 else
                    DTable.kz = 'A';

                 DTable.kapital -= tilg;

                 if (i == (index - 2))
                 {
                    DTable.rate = DTable.kapital;
                    DTable.zinsen = 0.0;
                    DTable.tilg = DTable.kapital;
                    DTable.rkapi = 0.0;
                 }
                 else
                 {
                    DTable.rate = runden (sumrat, rund_fakt);
                    DTable.zinsen = zins;
                    DTable.tilg = tilg;
                 }

                 TpPars->gesamt += zins;                /* Gesamtbelastung */

                 tmpFile.flush();
                 lseek (fd, loff, 0);
                 /* Füllen der Struktur */
                 old_tab.tilg = tilg;
                 old_tab.rate = 0.0;
                 old_tab.zinsen = zins;
                 old_tab.rkapi = old_tab.kapital + zins;
                 write (fd, &old_tab, sizeof (DTABLE));
                 old_tab.kapital = DTable.kapital;
                 old_tab.datum = DTable.datum;
                 tmpFile.flush();
                 lseek (fd, offset, 0);
                 loff = offset;
                 kap = DTable.kapital;
                 zins = 0.0;
                 tilg = 0.0;
                 sumrat = 0.0;
                 a_ind++;
                 ab_tag = tageber (ab_dat[a_ind]);
              } /* end if */

              if (DTable.datum <= ab_dat[0] && DTable.datum < TpPars->dvon &&
                  DTable.kz == 'R')
              {
                 if (TpPars->fixrate)
                    Abzug++;
                 else
                    real_rat--;

                 continue;
              }

              write (fd, &DTable, sizeof (DTABLE));
              offset += (long)sizeof (DTABLE);
           } /* end for */
        } /* end if "Antizipativ" */

        if (TpPars->fixrate == TRUE)
           TpPars->dbis = rat_dat[r_ind-1];

        TpPars->anzraten = real_rat;
        DTable.datum = (long)real_rat;          /* Laufzeit */
        DTable.kz = 'E';                        /* Ergebnis */
        DTable.kapital = TpPars->rahmen;
        DTable.tilg = TpPars->gesamt;
        DTable.rate = 0.0;
        TpPars->ezins = TpPars->gesamt - TpPars->rahmen;

        if (TpPars->zuschprz > 0.0)
           TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
        else
           TpPars->zuschuss = 0.0;

//      if (verzinsung == 1 || verzinsung == 2)
        if (verzinsung != 1 && verzinsung != 2)
           DTable.zinsen = TpPars->gesamt - TpPars->rahmen;
        else
           DTable.zinsen = kzi;

        TpPars->gesamt -= TpPars->zuschuss;

        // Annuitätenzuschuß berechnen und anzeigen

        if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
        {
           TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
           TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
           TpPars->antotal -= TpPars->zuschuss;
        }
        else
           TpPars->anzuschuss = TpPars->antotal = 0.0;

        DTable.rkapi = TpPars->lrate;
        write (fd, &DTable, sizeof (DTABLE));
        tmpFile.flush();
        lseek (fd, 0L, 0);
        tmpFile.flush();
        write (fd, &TpPars, sizeof (TPPARS));
        tmpFile.close ();
        return 0;
}

void TRech::init_global_vars ()
{
int i;

        ab_tag = 0L;
        zi_rat = 0.0;
        zi_kap = 0.0;
        dat_par = 0L;

        for (i = 0; i < 1200; i++)
        {
           rat_dat[i] = 0L;
           ab_dat[i] = 0L;
           rat_anz[i] = 0L;
        }
}

BOOL TRech::test_abschl (int am)
{
BOOL t1,t2,t3,t4,t5,t6;

        t1 = (TpPars->abschlry == 1 || TpPars->abschlry == 41);
        t2 = ((TpPars->abschlry == 3 || TpPars->abschlry == 43) && (am == 3 || am == 6 || am == 9 || am == 12));
        t3 = ((TpPars->abschlry == 6 || TpPars->abschlry == 46) && (am == 6 || am == 12));
        t4 = ((TpPars->abschlry == 12 || TpPars->abschlry == 52) && am == 12);
        t5 = (TpPars->abschlry == 47 && (am == 3 || am == 9));
        t6 = (TpPars->abschlry == 48 && (am == 2 || am == 8));

        if (t1 || t2 || t3 || t4 || t5 || t6)
           return TRUE;

        return FALSE;
}

/* Runden */

double TRech::runden (double zahl, int komma)
{
double vork, nachk;
long nk, nk1, splitter;

        if (zahl == 0.0)
           return 0.0;

        modf (zahl, &vork);
        nachk = zahl - vork;

        if (komma)
           nk = (double)(nachk * pow (10.0, (double)komma));

        nk1 = (double)(nachk * pow (10.0, (double)komma+1.0));
        splitter = nk1 - (nk * 10L);

        if (splitter >= 5L)
           nk++;

        if (komma == 0)
        {
           if (splitter >= 5)
              return vork+1.0;

           return vork;
        }

        nachk = (double)nk / pow (10.0, (double)komma);
        vork += nachk;
        return vork;
}

/* Tageberechnung */

long TRech::tageber (long date)
{
int tt_par, mm_par, jj_par;

        date_int (&tt_par, &mm_par, &jj_par, date);

        if (TpPars->tageb == 1 || TpPars->tageb == 4 || TpPars->tageb == 6)
        {
           if (TpPars->abschlry > 40 || TpPars->ultimo)
              if (tt_par >= 28 && mm_par == 2)
                 tt_par = 30;

           if (tt_par > 30)
              tg_par = (long)jj_par * 360L + (long)mm_par * 30L;
           else
              tg_par = (long)jj_par * 360L + ((long)mm_par - 1L) * 30L + (long)tt_par;
        }
        else
           tg_par = DateToDay (date);

        return tg_par;
}

/* Vorrechnen */

void TRech::vorrech ()
{
long tg;

        dat_par = ab_dat[a_ind];
        tg_par = tageber (dat_par);
        tg = tg_par - ab_tag;
        ab_tag = tg_par;

        if (verzinsung != 1)
        {
           zi_kap = kap * (double)tg * TpPars->zssoll / divisor;
           zi_rat = rat * (double)tg * TpPars->zssoll / divisor;
        }
        else
        {
           zi_kap = kap * (double)tg * TpPars->zssoll / (divisor - (double)tg * TpPars->zssoll);
           zi_rat = rat * (double)tg * TpPars->zssoll / (divisor - (double)tg * TpPars->zssoll);
        }
}

/* Einschränkung */

void TRech::einschr ()
{
long tg;

        rat = rat + (double)rat_anz[r_ind];

        if (TpPars->valuta == 0)
        {
           dat_par = rat_dat[r_ind];
           tg_par = tageber (dat_par);
           tg = ab_tag - tg_par;

           if (verzinsung == 1)
              zi_rat = zi_rat + (double)rat_anz[r_ind] * (double)tg *
                       TpPars->zssoll / (divisor - (double)tg *
                       TpPars->zssoll);
           else
              zi_rat = zi_rat + (double)rat_anz[r_ind] * (double)tg *
                       TpPars->zssoll / divisor;
        }

        r_ind++;
}

/* Abschlußberechnung */

void TRech::abschlus ()
{
        switch (reh)
        {
           case 0: kap += zi_kap;
                   rat += zi_rat;
           break;

           case 2: kap += (zi_kap + TpPars->spesen);
                   rat += zi_rat;
           break;
        }

        a_ind++;
}