Subversion Repositories public

Rev

Rev 70 | Blame | Compare with Previous | 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 version 3 of the License.                *
 *                                                                         *
 *   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.             *
 ***************************************************************************/

// TILGRECH.CPP
// Modul zur Berechnung eines Tilgungsplans.
// Die errechneten Daten werden in einer Datei zwischengespeichert und
// können so auf jede beliebige Art verwendet werden.
#include <klocale.h>
#include <kmessagebox.h>
#include <qfile.h>
#include <qstring.h>
#include <qdir.h>
#include <qdatetime.h>

#include <stdio.h>
#include <math.h>
#include <string.h>
#include <sys/stat.h>

#include "tilgplan.h"
#include "helper.h"

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 */;

// Wenn dieses Modul mit dem Flag "_ZINSAENDERUNG" compiliert wurde, kann
// eine Zinssatzänderung definiert werden. Dazu ist ein eigenes Dialog-
// fenster notwendig.

// Funktionen -------------------------------------------------------------

// Hauptprogramm
// Durch aufrufen dieser Routine wird ein Tilgungsplan auf Grund der
// übergebenen Parameter errechnet und in einer Datei abgelegt.
// Diese kann dann weiter bearbeitet werden.
//
// Die übergebenen Parameter enthalten auch Steuerkennzeichen. So kann auch
// der Effektivzinssatz berechnet werden. Dazu muss der Kredit zunächst
// normal durchgerechnet werden. Anschliessen wird mit der errechneten Rate,
// jedoch ohne Spesen, Gebühren etc. der Plan für ein Jahr noch einmal
// gerechnet. Die so ermittelten Zinsen ergeben den Effektivzinssatz.
//

int TRech::tilgpl ()
{
int day, mon, year, akt_mon, akt_year, i, j;

        // initialisieren
        init_global_vars ();

        if (TpPars->dvon == 0L)
           return 2;                    // 1. Einschränkung nicht vorhanden

        // Datum der ersten Einschränkung korrigieren falls notwendig
        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);
        }

        // Auszahlungsdatum überprüfen

        if (TpPars->ragab == 0L)
           return 8;                    // Auszahlungsdatum nicht vorhanden

        // Auszahlungsdatum auf Gültigkeit überprüfen

        if (TpPars->ragab > TpPars->dvon)
           return 3;                    // Auszahlungsdatum > 1. Einschränkung

        if (TpPars->effekt && TpPars->rate <= 0.0)
           return 29;                   // Keine Rate, kein Effektivzins!

        // Abschlußrhythmus überprüfen

        if (TpPars->effekt && TpPars->abschlry != 12 && TpPars->abschlry != 52)
           return 26;                   // Für Effektivzinssatzberechnung nur jährlicher Abschluss erlaubt

        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;                   // ungültiger Abschlußrythmus

        if (TpPars->abschlry > 40)      // Abschlüsse auf Ultimo rechnen?
           TpPars->abschl = 0L;         // Ja, Abschlußdatum initialisieren

        // Abschlußdatum überprüfen

        if (TpPars->abschl > 0L && TpPars->abschl < TpPars->ragab)
           return 4;                    // Abschlußdatum < Auszahlungsdatum

        if (TpPars->abschl == 0L && TpPars->abschlry < 41)
           return 10;                   // Abschlußdatum muß angegeben werden

        // 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;
        }

        // Ratenvorgabe?

        if (TpPars->fixrate)
        {
           if (TpPars->rate < 0.0)
              return 16;                // Ratenvorgabe negativ
           else if (TpPars->rate == 0.0)
              return 15;                // keine Ratenvorgabe

           // Datum der letzten Einschränkung initialisieren
           TpPars->dbis = 0.0;
        }
        else                            // Rate initialisieren
           TpPars->rate = 0.0;

        // Datum der letzten Einschränkung überprüfen

        if (!TpPars->fixrate)           // Nur wenn keine Ratenvorgabe
        {
           date_int (&i, &akt_mon, &akt_year, TpPars->dvon);
           date_int (&day, &akt_mon, &akt_year, TpPars->dbis);
           set_feb (akt_year);

           // Da das Datum der letzten Einschränkung nur aus Monat und
           // Jahr besteht, muß noch der Tag hinzugefügt werden, um
           // damit rechnen zu können.

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

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

           // Datum mit 1.Einschränkung gegenprüfen

           if (TpPars->dvon > TpPars->dbis)
              return 5;                 // 1. Einschränkung > letzte Einschränkung

           // letzte Einschränkung mit Ratenleiste gegenprüfen

           if (TpPars->raplan[akt_mon-1] <= 0)
              return 19;                // letzte Einschränkung oder Ratenleiste ungültig
        }

        // Endfälligkeitsdatum überprüfen (falls vorhanden)

        if (TpPars->endfaell > 0L && TpPars->dbis > TpPars->endfaell)
           return 6;                    // letzte Einschränkung > Endfälligkeit

        // Ratenleiste berprüfen

        i = j = 0;

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

           i++;
        }

        if (!j)
           return 7;                    // Es wurde keine Rate definiert

        // 1. Einschränkung mit Ratenleiste gegenprüfen

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

        if (TpPars->raplan[mon-1] <= 0)
           return 18;                   // 1. Einschränkung oder Ratenleiste ungültig

        // Verzinsungsart überprüfen

        if (TpPars->verzart == 0 || TpPars->verzart == 2 || TpPars->verzart == 8)
           verzinsung = 0;              // Permanent dekursiv
        else if (TpPars->verzart == 3)
           verzinsung = 1;              // Antizipativ
        else if (TpPars->verzart == 7)
           verzinsung = 2;              // Dekursiv
        else if (TpPars->verzart == 4)
           verzinsung = 3;              // Quasiantizipativ
        else
           return 12;                   // ungültige Verzinsungsart

        if (TpPars->effekt && (verzinsung == 1 || verzinsung == 3))
           return 28;                   // Effektivzinss. nur bei dekursiv möglich

        // Verzinsungsart mit Abschlußrhythmus gegenprüfen

        if (TpPars->verzart == 1 && TpPars->abschlry != 43 &&
                TpPars->abschlry != 46 && TpPars->abschlry != 52)
           return 9;                    // Verzinsung in Bezug auf Abschlußrhythmus ungültig

#ifdef _ZINSAENDERUNG
        // Zinssatzänderung mit Verzinsungsart gegenprüfen

        if (TpPars->ziaend && (verzinsung == 1 || verzinsung == 3))
           return 23;                   // Zinssatzänderung unter Antizipativ nicht möglich
#endif

        // Ratenart überprüfen

        if (TpPars->ratenart < 0 || TpPars->ratenart > 3)
           return 13;                   // ungültige Ratenart

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

        // Divisor setzen

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

        // Erstellen einer Datumstabelle

        if (verzinsung == 0 || verzinsung == 2) // Dekursiv?
        {
           if ((i = DekursivTable ()) != 0)
              return i;
        }
        else                                    // Antizipativ
        {
           if ((i = AntizipativTable ()) != 0)
              return i;
        }

        // Berechnung der Rate

        a_ind = r_ind = 0;

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

        // Erstellen eines Ratenplans

        GetRate (TpPars->rahmen, TpPars->ragab, TpPars->dvon);

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

#ifdef _ZINSAENDERUNG

int TRech::GetZiaend ()
{
QString hdir = QDir::homeDirPath ();
QFile tmpFile;
int fd;
struct stat sbuf;
ZIAEND Zi;

        // Plausibilitätsprüfung der eingebenen Daten
        hdir.append("/.zinsaend.dat");
        tmpFile.setName(hdir);

        if (tmpFile.open(IO_ReadWrite) == FALSE)
        {
           KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
           return 23;
        }
        
        fd = tmpFile.handle();
        fstat (fd, &sbuf);

        if (sbuf.st_size == 0L)
        {
           tmpFile.close ();
           return 0;
        }

        while (read (fd, &Zi, sizeof(ZIAEND)) == sizeof(ZIAEND))
        {
           if (Zi.Datum <= TpPars->dvon)
           {
              tmpFile.close ();
              return 24;
           }

           if (Zi.Datum >= TpPars->dbis)
           {
              tmpFile.close ();
              return 25;
           }
        }

        tmpFile.close ();
        return 0;
}

#endif


int TRech::DekursivTable ()
{
long tage;
int vday, day, mon, year, akt_day, akt_mon, iday, imon, iyear;
int at, am, aj;
BOOL abschluss, r_yet;
long lab;
QDate dat1, dat2;

        // Wurde eine fixe Rate vorgegeben und ein Enfälligkeitsdatum
        // angegeben, muß die letzte Einschränkung gleich dem
        // Endfälligkeitsdatum sein.

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

        // Wurde eine fixe Rate vorgegeben und keine letzte Einschränkung
        // und keine Endfälligkeit, werden 100 Jahre im voraus gesetzt.
        // Das ist die maximale Laufzeit.

        if (TpPars->dbis == 0L)
        {
           QDate dt;
           date_int(&day, &mon, &year, TpPars->ragab);
           dt.setYMD(year, mon, day);
           dt = dt.addYears(99);
           TpPars->dbis = dt.year() * 10000L + dt.month() * 100L + dt.day();
        }

        // Wenn auf Ultimo gerechnet wird, muß der Tag der letzten
        // Einschränkung auf den letzten des Monats gesetzt werden.
        // Einzige Ausnahme: Verzinsungsart 7. Hier muß der Tag auf den
        // 1. eines Monats gesetzt werden.

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

           if (TpPars->verzart == 7)
              day = 1;
           else
              day = MonLeiste[mon-1];

           TpPars->dbis = make_date (day, mon, year);
        }

        // überprüfen der Laufzeit auf Grund der eingegebenen Daten

        if (TpPars->endfaell > 0L)
        {
           QDate dt1, dt2;
           date_int(&day, &mon, &year, TpPars->endfaell);
           dt1.setYMD(year, mon, day);
           date_int(&day, &mon, &year, TpPars->ragab);
           dt2.setYMD(year, mon, day);
           tage = dt2.daysTo(dt1);
//         tage = DateToDay (TpPars->endfaell) - DateToDay (TpPars->ragab);
        }
        else
        {
           QDate dt1, dt2;
           date_int(&day, &mon, &year, TpPars->dbis);
           dt1.setYMD(year, mon, day);
           date_int(&day, &mon, &year, TpPars->ragab);
           dt2.setYMD(year, mon, day);
           tage = dt2.daysTo(dt1);
//         tage = DateToDay (TpPars->dbis) - DateToDay (TpPars->ragab);
        }

        if (tage > 36524L)
           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 && a_ind < 1200 && r_ind < 1200)
        {
           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 (test_abschl (akt_mon+1) && 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)
              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)           // Jahreswechsel
           {
              akt_mon = 0;
              year++;
           }

           date_int(&iday, &imon, &iyear, r_dat);
           dat1.setYMD(iyear, imon, iday);
           date_int(&iday, &imon, &iyear, TpPars->ragab);
           dat2.setYMD(iyear, imon, iday);
           pos = dat2.daysTo(dat1);
//         pos = DateToDay (r_dat) - DateToDay (TpPars->ragab), r_dat, TpPars->ragab);
        }

        if (TpPars->effekt && (r_ind >= 1200 || a_ind >= 1200))
           return 20;                   // Rechenfehler

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

        TpPars->dbis = ldat;
        max_abs = a_ind;
        max_rat = r_ind;
        return 0;
}

int TRech::AntizipativTable ()
{
long tage;
int vday, day, mon, year, akt_day, akt_mon;
int at, am, aj;
BOOL abschluss, r_yet;
long lab;

        // Wurde eine fixe Rate vorgegeben und ein Enfälligkeitsdatum
        // angegeben, muß die letzte Einschränkung gleich dem
        // Endfälligkeitsdatum sein.

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

        // Wurde eine fixe Rate vorgegeben und keine letzte Einschränkung
        // und keine Endfälligkeit, werden 100 Jahre im voraus gesetzt.
        // Das ist die maximale Laufzeit.

        if (TpPars->dbis == 0L)
        {
           QDate dt;
           date_int(&day, &mon, &year, TpPars->ragab);
           dt.setYMD(year, mon, day);
           dt = dt.addYears(99);                // 99 Jahre ist maximale Laufzeit
           TpPars->dbis = dt.year() * 10000L + dt.month() * 100L + dt.day();
        }

        // Wenn auf Ultimo gerechnet wird, muß der Tag der letzten
        // Einschränkung auf den letzten des Monats gesetzt werden.
        // Einzige Ausnahme: Verzinsungsart 7. Hier muß der Tag auf den
        // 1. eines Monats gesetzt werden.

        if (TpPars->ultimo)
        {
           if (TpPars->verzart == 3)
              day = 1;
           else
           {
              date_int (&day, &mon, &year, TpPars->dbis);
              day = MonLeiste[mon-1];
           }

           TpPars->dbis = make_date (day, mon, year);
        }
        else
        {
           date_int (&day, &mon, &year, TpPars->dbis);
           day = 1;
           TpPars->dbis = make_date (day, mon, year);
        }
         
        // überprüfen der Laufzeit auf Grund der eingegebenen Daten

        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)
           {
              ab_dat[a_ind] = TpPars->ragab;
              lab = TpPars->ragab;
              TpPars->abschl = TpPars->ragab;
              abschluss = TRUE;
              a_ind++;
           }
           else if (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;
              a_ind++;
           }

           // Einschränkungsdatum

           if (TpPars->ultimo)
              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)           // Jahreswechsel
           {
              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;
        return 0;
}

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

        if (zahl == 0.0)
           return 0.0;

        nk = 0L;
        modf (zahl, &vork);
        nachk = zahl - vork;

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

        nk1 = (long)((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;
}

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;
}

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;
}

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++;
}

// Erstellen eines Ratenplans

double TRech::GetRate (double rahmen, long ragab, long dvon)
{
double ergrate;

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

        if (rat_dat[r_ind] < dvon)
           while (rat_dat[r_ind] < dvon && r_ind < max_rat)
              r_ind++;

        dat_par = ragab;
        tageber (dat_par);
        kap = rahmen + TpPars->kosten;
        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;
           ergrate = runden (rat, rund_fakt);

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

        return rat;
}

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

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

// #$10100
int TRech::Ratenplan ()
{
        if (verzinsung == 0 || verzinsung == 2)
        {
           if (TpPars->effekt)
           {
           int i = 0;
           int ret;

              TpPars->effformel = TpPars->zssoll;

              while (i < 10000 && (ret = DekursivPlan ()) == -2)
              {
                 TpPars->zssoll = TpPars->effformel;
                 i++;
              }

              if (ret != -2)
                 return ret;
fprintf (stderr, "bzins: %.2f, ezins: %.2f\n", TpPars->gewicht, TpPars->ezins);
              return 0;
           }

           return DekursivPlan ();
        }

        return AntizipativPlan ();
}

// #$10110
int TRech::DekursivPlan ()
{
QString hdir = QDir::homeDirPath ();
QFile tmpFile, zaf;
int fd, index, i;
int real_rat, Abzug;
long tg, effend;
double zins, tilg, zi1, zi2, kzi;
long offset;
BOOL stop;
#ifdef _ZINSAENDERUNG
   int fdZins;
   long zoff, LastAend;
   ZIAEND Zi;
   double aZins;
   struct stat sbuf;
#endif


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

        if (!TpPars->effekt)
        {
           if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
           {
              KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
              return 1;
           }
        }
        else
        {
           if (tmpFile.open(IO_ReadOnly) == FALSE)
           {
              KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
              return 1;
           }
        }

        fd = tmpFile.handle();
#ifdef _ZINSAENDERUNG
        // Wenn eine Zinssatzänderung gewünscht wurde, muß die Änderungs-
        // datei geöffnet werden.

        zoff = 0L;
        LastAend = 0L;          // Beinhaltet Datum der letzten Zinssatzänderung
        aZins = 0.0;
        memset (&Zi, 0, sizeof(ZIAEND));

        if (TpPars->ziaend)
        {
           hdir = QDir::homeDirPath ();
           hdir.append("/.zinsaend.dat");
           zaf.setName(hdir);
           fdZins = -1;

           if (zaf.open(IO_ReadOnly) == FALSE)
              TpPars->ziaend = FALSE;
           else
           {
              fdZins = zaf.handle();
              fstat (fdZins, &sbuf);

              if (sbuf.st_size == 0L)
                 TpPars->ziaend = FALSE;
              else
              {
                 read (fdZins, &Zi, sizeof(ZIAEND));
                 zoff += (long)sizeof(ZIAEND);
              }
           }

           if (!TpPars->ziaend && fdZins != -1)
              zaf.close ();
        }
#endif


        offset = 0L;
        index = max_abs + max_rat;

        /* Ausgangsdaten schreiben */
        if (!TpPars->effekt)
        {
           write (fd, TpPars, sizeof (TPPARS));
           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

        if (TpPars->effekt)
           effend = TpPars->dvon + 10000L;      // 1 Jahr für Effektivzinsberechnung
        else
           effend = 0L;

        /* Spesen dürfen nur einmal bei der Auszahlung auf das Kapital
         * aufgeschlagen werden.
         */
        if (!TpPars->effekt)
        {
           DTable.datum = TpPars->ragab;
           DTable.kz = 'U';             // Auszahlung
           DTable.kapital = kap;
           DTable.tilg = 0.0;
           DTable.rate = 0.0;
           DTable.zinsen = TpPars->kosten;
           DTable.rkapi = kap + TpPars->kosten;
           kap += TpPars->kosten;

           write (fd, &DTable, sizeof (DTABLE));
           offset += (long)sizeof (DTABLE);
        }

        /* Schleife zur Berechnung der Gesamtbelastung (Dekursiv) */

        for (i = 0; i < index; i++)
        {
#ifdef _ZINSAENDERUNG
           // Ist eine Zinssatzänderung gewünscht?

           if ((Zi.Datum < rat_dat[r_ind-1] || Zi.Datum < ab_dat[a_ind]) &&
               zoff <= sbuf.st_size && TpPars->ziaend)
           {
              DTable.datum = Zi.Datum;
              DTable.kz = 'Z';
              DTable.kapital = kap;
              index++;

              if (a_ind > 0)
              {
                 if (ab_dat[a_ind-1] < Zi.Datum)
                    ldat = ab_dat[a_ind-1];
                 else
                    ldat = Zi.Datum;

                 tg = tageber (Zi.Datum) - tageber (ldat);
              }
              else
                 tg = tageber (Zi.Datum) - tageber (TpPars->ragab);

              aZins = kap * (double)tg * TpPars->zssoll / divisor;
              kap += runden (aZins, rund_fakt);
              LastAend = Zi.Datum;
              DTable.rate = Zi.Zins;
              DekZiAend (fdZins, &zoff, sbuf.st_size, &Zi);
              kap = DTable.kapital;
           }
           else if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
#else

           if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
#endif

           {
              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];
#ifdef _ZINSAENDERUNG
                 if (LastAend && LastAend > ldat)
                    ldat = LastAend;
#endif

                 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;
#ifdef _ZINSAENDERUNG
              if (LastAend)
              {
                 LastAend = 0L;
                 zi1 += aZins;
              }
#endif

              zi1 = runden (zi1, rund_fakt);
              zins += zi1;
              kzi += zi1;

              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 = (kap < rat) ? rat - kap : kap - rat;
                    zi2 = rat - zi2 + zins;
//                  zi2 = rat + ((TpPars->gesamt + zins) - (rat * (LFLOAT)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];
#ifdef _ZINSAENDERUNG
                 if (LastAend && LastAend > ldat)
                    LastAend = 0L;
#endif

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

                 if (tg > 0)
                 {
                    zi1 = kap * (double)tg * TpPars->zssoll / divisor;
#ifdef _ZINSAENDERUNG
                    if (LastAend)
                    { 
                       LastAend = 0L;
                       zi1 += aZins;
                    }
#endif

                    zins += zi1;
                    kzi += runden (zi1, rund_fakt);
                    zins = runden (zins, rund_fakt);
                 }
#ifdef _ZINSAENDERUNG
                 else if (LastAend)
                    LastAend = 0L;
#endif

              }

              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 < TpPars->dvon && DTable.kz == 'R')
           {
              if (TpPars->fixrate)
                 Abzug++;
              else
                 real_rat--;

              continue;
           }

           if (!TpPars->effekt)
           {
              write (fd, &DTable, sizeof (DTABLE));
              offset += (long)sizeof (DTABLE);
           }
           else if (DTable.datum >= effend)
              break;
        } /* end for */

        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;

        DTable.zinsen = TpPars->gesamt - TpPars->rahmen;
        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;

        if (!TpPars->effekt)
           write (fd, &DTable, sizeof (DTABLE));
#ifdef _ZINSAENDERUNG
//      if (TpPars->gewicht > 0.0)
//         TpPars->zssoll = TpPars->gewicht;

        zaf.close();
#endif

        tmpFile.flush();

        if (!TpPars->effekt)
        {
           lseek (fd, 0L, 0);
           write (fd, TpPars, sizeof (TPPARS));
        }
        else
        {
           // Zinsen nach einem Jahr ermitteln
           tmpFile.flush();
           lseek (fd, (long)sizeof(TPPARS), 0);
           zins = 0.0;

           while (read (fd, &DTable, sizeof(DTABLE)) >= sizeof(DTABLE))
           {
              if (DTable.kz == 'R' && DTable.datum >= effend)
                 break;

              if (DTable.kz == 'R')
                 zins += DTable.zinsen;
           }

           if ((TpPars->ezins - 0.1) < zins && (TpPars->ezins + 0.1) > zins)
           {
              tmpFile.close();
              TpPars->gewicht = zins;
              return 0;
           }
           else
           {
              tmpFile.close();
              TpPars->gewicht = zins;

              if (TpPars->ezins < zins)
                 TpPars->effformel += 0.0001;
              else
                 TpPars->effformel -= 0.0001;

              return -2;                // Für nächste Iteration präparieren.
           }
        }

        tmpFile.close ();
        return 0;
}

#ifdef _ZINSAENDERUNG
void TRech::DekZiAend (int fdZins, long *zoff, long size, ZIAEND *Zi)
{
int old_rind, old_aind;
long datum;
double old_kap;

        TpPars->gewicht = TpPars->zssoll;
        TpPars->zssoll = Zi->Zins;

        if (Zi->Rate)
        {
           old_kap = kap;
           old_rind = r_ind;
           old_aind = a_ind;

           if (rat_dat[r_ind] > ab_dat[a_ind])
              datum = ab_dat[a_ind];
           else
              datum = rat_dat[r_ind];

           GetRate (kap, Zi->Datum, datum);
           kap = old_kap;
           r_ind = old_rind;
           a_ind = old_aind;
           TpPars->ergrate = rat;
        }
        else if (Zi->FixRate)
        {
           rat = Zi->NewRate;
           TpPars->ergrate = rat;
        }

        if (*zoff < size)
           read (fdZins, Zi, sizeof(ZIAEND));
        else
           close (fdZins);

        *zoff += (long)sizeof(ZIAEND);
}

#endif

int TRech::AntizipativPlan ()
{
QString hdir = QDir::homeDirPath ();
QFile tmpFile;
int fd, index, i;
int real_rat, Abzug;
long t1, t2, r_dat, old_par, r_tg, a_tg;
double zins, tilg, kzi, sumrat;
long offset, loff;
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;
        }
        

        fd = tmpFile.handle();
        offset = 0L;
        index = max_abs - 1 + max_rat;

        /* Ausgangsdaten schreiben */
        write (fd, TpPars, sizeof (TPPARS));
        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;
        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 (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);
        r_dat = 0L;

        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 (t2 < 0L)
                 t2 = 0L;

              // Berechnung der letzten Rate
              if (rat > (DTable.rkapi - TpPars->kapital))
                 rat = runden (DTable.rkapi - TpPars->kapital, rund_fakt);

              sumrat += rat;

//              if (reh == 1)           // Kapitalraten
                 kap -= rat;

              if (reh != 1)             // Pauschalraten
              {
                 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                      // Kapitalraten
//               kzi = kap * (tg_par - tg_alt) * TpPars->zssoll / divisor;
                 kzi = kap * (t1 - t2) * TpPars->zssoll / divisor;

              kzi = runden (kzi, rund_fakt);
              tg_alt = tg_par;
              zins += kzi;

              if (reh == 1)             // Kapitalraten
                 DTable.rkapi = DTable.kapital - sumrat;
              else                      // Pauschalraten
                 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;
                 }
              }

              if (reh == 1)             // Kapitalraten
                 DTable.tilg = rat;
              else                      // Pauschalraten
                 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';

              if (a_ind > 1)
              {
                 old_par = tg_par; 

                 if (reh == 1)                  // Kapitalraten
                 {
                    r_tg = tageber (r_dat);
                    a_tg = tageber (ab_dat[a_ind-1]);
                    t1 = r_tg - a_tg;
                    t2 = 0L;
                 }
                 else
                 {
                    a_tg = tageber (ab_dat[a_ind]);
                    tageber (ab_dat[a_ind-1]);
                    t1 = a_tg - tg_par;
                    tageber (r_dat);
                    t2 = ab_tag - tg_par;
                 }

                 tg_par = old_par;

                 if (reh != 1)                  // Pauschalraten
                 {
                    kzi = DTable.kapital * 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                           // Kapitalraten
                    kzi = DTable.kapital * t1 * TpPars->zssoll / divisor;

                 kzi = runden (kzi, rund_fakt);
                 zins += kzi;

                 if (reh != 1)
                 {
                    tilg -= kzi;
                    DTable.rkapi = DTable.kapital - tilg;
                 }
              }

              DTable.kapital -= tilg;
              r_dat = rat_dat[r_ind];

              if (i == (index - 2))
              {
                 DTable.rate = DTable.kapital;
                 TpPars->lrate = DTable.rate;
                 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;

              if (reh == 1)
                 old_tab.rkapi = old_tab.kapital;
              else
                 old_tab.rkapi = old_tab.kapital + zins;

              write (fd, &old_tab, sizeof (DTABLE));
              old_tab.kapital = DTable.kapital;
              old_tab.datum = DTable.datum;
              lseek (fd, offset, 0);
              loff = offset;

//              if (reh == 1)                   // Kapitalraten
                 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 */

        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;

        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);
        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;
        reh = 0;
        divisor = 0.0;
        a_ind = 0;
        r_ind = 0;
        max_abs = max_rat = 0;
        pos = 0L;
        a_dat = 0L;
        tg_par = tg_alt = 0L;
        r_dat = 0L;
        ldat = 0L;
        rat = kap = 0.0;

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