0,0 → 1,1536 |
/*************************************************************************** |
* 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 <stdio.h> |
#include <math.h> |
#include <string.h> |
#include <sys/stat.h> |
#include <iostream.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 */; |
|
// Klassendefinition: DLG_ZIAEND ------------------------------------------ |
|
// Wenn dieses Modul mit dem Flag "_ZINSAENDERUNG" compiliert wurde, kann |
// eine Zinssatzänderung definiert werden. Dazu ist ein eigenes Dialog- |
// fenster notwendig. Die Klasse dafür ist hier definiert. |
// Das Dialogfenster kann nur dann aufgerufen werden, wenn das Mutter- |
// modul den Zeiger auf sich selbst übergeben hat (SetParent). |
|
|
// Funktionen ------------------------------------------------------------- |
|
// Hauptprogramm |
// Druch aufrufen dieser Routine wird ein Tilgungsplan auf Grund der |
// übergebenen Parameter errechnet und in einer Datei abgelegt. |
// Diese kann dann weiter bearbeitet werden. |
|
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 |
|
// Abschlußrhythmus überprüfen |
|
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 |
|
// 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; |
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) |
{ |
tage = (99L * 365L) + (99L / 4L); // 99 Jahre ist maximale Laufzeit |
TpPars->dbis = DayToDate (tage + DateToDay (TpPars->ragab)); |
} |
|
// 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) |
tage = DateToDay (TpPars->endfaell) - DateToDay (TpPars->ragab); |
else |
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++; |
} |
|
pos = DateToDay (r_dat) - DateToDay (TpPars->ragab); |
} |
|
if (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) |
{ |
tage = (99L * 365L) + (99L / 4L); // 99 Jahre ist maximale Laufzeit |
TpPars->dbis = DayToDate (tage + DateToDay (TpPars->ragab)); |
} |
|
// 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; |
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) |
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; |
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 (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(); |
#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 */ |
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 |
|
/* 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; |
DekZiAend (fdZins, &zoff, sbuf.st_size, &Zi); |
kap = DTable.kapital; |
DTable.rate = Zi.Zins; |
} |
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; |
} |
|
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 = 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; |
write (fd, &DTable, sizeof (DTABLE)); |
#ifdef _ZINSAENDERUNG |
if (TpPars->gewicht > 0.0) |
TpPars->zssoll = TpPars->gewicht; |
|
zaf.close(); |
#endif |
tmpFile.flush(); |
lseek (fd, 0L, 0); |
write (fd, TpPars, sizeof (TPPARS)); |
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; |
|
for (i = 0; i < 1200; i++) |
{ |
rat_dat[i] = 0L; |
ab_dat[i] = 0L; |
rat_anz[i] = 0L; |
} |
} |