Subversion Repositories public

Rev

Rev 64 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
53 andreas 1
/***************************************************************************
2
 *   Copyright (C) 2007 by Andreas Theofilu                                *
3
 *   andreas@TheoSys.at                                                    *
4
 *                                                                         *
5
 *   This program is free software; you can redistribute it and/or modify  *
6
 *   it under the terms of the GNU General Public License as published by  *
7
 *   the Free Software Foundation version 3 of the License.                *
8
 *                                                                         *
9
 *   This program is distributed in the hope that it will be useful,       *
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
12
 *   GNU General Public License for more details.                          *
13
 *                                                                         *
14
 *   You should have received a copy of the GNU General Public License     *
15
 *   along with this program; if not, write to the                         *
16
 *   Free Software Foundation, Inc.,                                       *
17
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
18
 ***************************************************************************/
19
 
20
// TILGRECH.CPP
21
// Modul zur Berechnung eines Tilgungsplans.
22
// Die errechneten Daten werden in einer Datei zwischengespeichert und
23
// können so auf jede beliebige Art verwendet werden.
24
#include <klocale.h>
25
#include <kmessagebox.h>
26
#include <qfile.h>
27
#include <qstring.h>
28
#include <qdir.h>
60 andreas 29
#include <qdatetime.h>
53 andreas 30
 
31
#include <stdio.h>
32
#include <math.h>
33
#include <string.h>
34
#include <sys/stat.h>
35
 
36
#include "tilgplan.h"
37
#include "helper.h"
38
 
39
int MonLeiste[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
40
		 /*  Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez */;
41
 
42
// Wenn dieses Modul mit dem Flag "_ZINSAENDERUNG" compiliert wurde, kann
43
// eine Zinssatzänderung definiert werden. Dazu ist ein eigenes Dialog-
60 andreas 44
// fenster notwendig.
53 andreas 45
 
46
// Funktionen -------------------------------------------------------------
47
 
48
// Hauptprogramm
60 andreas 49
// Durch aufrufen dieser Routine wird ein Tilgungsplan auf Grund der
53 andreas 50
// übergebenen Parameter errechnet und in einer Datei abgelegt.
51
// Diese kann dann weiter bearbeitet werden.
60 andreas 52
//
53
// Die übergebenen Parameter enthalten auch Steuerkennzeichen. So kann auch
54
// der Effektivzinssatz berechnet werden. Dazu muss der Kredit zunächst
55
// normal durchgerechnet werden. Anschliessen wird mit der errechneten Rate,
56
// jedoch ohne Spesen, Gebühren etc. der Plan für ein Jahr noch einmal
57
// gerechnet. Die so ermittelten Zinsen ergeben den Effektivzinssatz.
58
//
53 andreas 59
 
60
int TRech::tilgpl ()
61
{
62
int day, mon, year, akt_mon, akt_year, i, j;
63
 
64
	// initialisieren
65
	init_global_vars ();
66
 
67
	if (TpPars->dvon == 0L)
68
	   return 2;			// 1. Einschränkung nicht vorhanden
69
 
70
        // Datum der ersten Einschränkung korrigieren falls notwendig
71
	date_int (&day, &mon, &year, TpPars->dvon);
72
 
73
	if (TpPars->ultimo)		// Wenn Ultimo Datum korrigieren
74
	{
75
	   set_feb (year);
76
	   day = MonLeiste[mon-1];
77
	   TpPars->dvon = make_date (day, mon, year);
78
	}
79
 
80
	// Auszahlungsdatum überprüfen
81
 
82
	if (TpPars->ragab == 0L)
83
	   return 8;			// Auszahlungsdatum nicht vorhanden
84
 
85
	// Auszahlungsdatum auf Gültigkeit überprüfen
86
 
87
	if (TpPars->ragab > TpPars->dvon)
88
	   return 3;			// Auszahlungsdatum > 1. Einschränkung
89
 
60 andreas 90
	if (TpPars->effekt && TpPars->rate <= 0.0)
91
	   return 29;			// Keine Rate, kein Effektivzins!
92
 
53 andreas 93
	// Abschlußrhythmus überprüfen
94
 
60 andreas 95
	if (TpPars->effekt && TpPars->abschlry != 12 && TpPars->abschlry != 52)
96
	   return 26;			// Für Effektivzinssatzberechnung nur jährlicher Abschluss erlaubt
97
 
53 andreas 98
	if (TpPars->abschlry != 1 && TpPars->abschlry != 3 && TpPars->abschlry != 6 &&
99
	    TpPars->abschlry != 12 && TpPars->abschlry != 41 && TpPars->abschlry != 43 &&
100
	    TpPars->abschlry != 46 && TpPars->abschlry != 47 && TpPars->abschlry != 48 &&
101
	    TpPars->abschlry != 52)
102
	   return 11;			// ungültiger Abschlußrythmus
103
 
104
	if (TpPars->abschlry > 40)	// Abschlüsse auf Ultimo rechnen?
105
	   TpPars->abschl = 0L;		// Ja, Abschlußdatum initialisieren
106
 
107
	// Abschlußdatum überprüfen
108
 
109
	if (TpPars->abschl > 0L && TpPars->abschl < TpPars->ragab)
110
	   return 4;			// Abschlußdatum < Auszahlungsdatum
111
 
112
	if (TpPars->abschl == 0L && TpPars->abschlry < 41)
113
	   return 10;			// Abschlußdatum muß angegeben werden
114
 
115
	// Abschlußplan erstellen;
116
 
117
	for (i = 0; i < 12; i++)
118
	   AbschlPlan[i] = 0;
119
 
120
	switch (TpPars->abschlry)
121
	{
122
	   case  1:
123
           case 41: for (i = 0; i < 12; i++)
124
		       AbschlPlan[i] = 1;
125
	   break;
126
 
127
	   case  3:
128
           case 43: AbschlPlan[2] = 1;
129
		    AbschlPlan[5] = 1;
130
		    AbschlPlan[8] = 1;
131
		    AbschlPlan[11] = 1;
132
	   break;
133
 
134
	   case  6:
135
           case 46: AbschlPlan[5] = 1;
136
		    AbschlPlan[11] = 1;
137
	   break;
138
 
139
	   case 12:
140
	   case 52: AbschlPlan[11] = 1;
141
	   break;
142
 
143
	   case 47: AbschlPlan[2] = 1;
144
		    AbschlPlan[8] = 1;
145
	   break;
146
 
147
	   case 48: AbschlPlan[1] = 1;
148
		    AbschlPlan[7] = 1;
149
	   break;
150
	}
151
 
152
	// Ratenvorgabe?
153
 
154
	if (TpPars->fixrate)
155
	{
156
	   if (TpPars->rate < 0.0)
157
	      return 16;		// Ratenvorgabe negativ
158
	   else if (TpPars->rate == 0.0)
159
	      return 15;		// keine Ratenvorgabe
160
 
161
	   // Datum der letzten Einschränkung initialisieren
162
	   TpPars->dbis = 0.0;
163
        }
164
	else				// Rate initialisieren
165
	   TpPars->rate = 0.0;
166
 
167
	// Datum der letzten Einschränkung überprüfen
168
 
169
	if (!TpPars->fixrate)		// Nur wenn keine Ratenvorgabe
170
	{
171
	   date_int (&i, &akt_mon, &akt_year, TpPars->dvon);
172
	   date_int (&day, &akt_mon, &akt_year, TpPars->dbis);
173
	   set_feb (akt_year);
174
 
175
	   // Da das Datum der letzten Einschränkung nur aus Monat und
176
	   // Jahr besteht, muß noch der Tag hinzugefügt werden, um
177
	   // damit rechnen zu können.
178
 
179
	   if (i > MonLeiste[akt_mon-1])
180
	      i = MonLeiste[akt_mon-1];
181
 
182
	   TpPars->dbis = make_date (i, akt_mon, akt_year);
183
 
184
	   // Datum mit 1.Einschränkung gegenprüfen
185
 
186
	   if (TpPars->dvon > TpPars->dbis)
187
              return 5;			// 1. Einschränkung > letzte Einschränkung
188
 
189
	   // letzte Einschränkung mit Ratenleiste gegenprüfen
190
 
191
	   if (TpPars->raplan[akt_mon-1] <= 0)
192
              return 19;		// letzte Einschränkung oder Ratenleiste ungültig
193
	}
194
 
195
	// Endfälligkeitsdatum überprüfen (falls vorhanden)
196
 
197
	if (TpPars->endfaell > 0L && TpPars->dbis > TpPars->endfaell)
198
	   return 6;			// letzte Einschränkung > Endfälligkeit
199
 
200
	// Ratenleiste berprüfen
201
 
202
	i = j = 0;
203
 
204
	while (i < 12)
205
	{
206
	   if (TpPars->raplan[i] > 0)
207
	   {
208
	      j = 1;
209
	      break;
210
	   }
211
 
212
	   i++;
213
	}
214
 
215
	if (!j)
216
	   return 7;			// Es wurde keine Rate definiert
217
 
218
	// 1. Einschränkung mit Ratenleiste gegenprüfen
219
 
220
	date_int (&day, &mon, &year, TpPars->dvon);
221
 
222
	if (TpPars->raplan[mon-1] <= 0)
223
	   return 18;			// 1. Einschränkung oder Ratenleiste ungültig
224
 
225
	// Verzinsungsart überprüfen
226
 
227
	if (TpPars->verzart == 0 || TpPars->verzart == 2 || TpPars->verzart == 8)
228
	   verzinsung = 0;		// Permanent dekursiv
229
	else if (TpPars->verzart == 3)
230
	   verzinsung = 1;		// Antizipativ
231
	else if (TpPars->verzart == 7)
232
	   verzinsung = 2;		// Dekursiv
233
	else if (TpPars->verzart == 4)
234
	   verzinsung = 3;		// Quasiantizipativ
235
	else
236
	   return 12;			// ungültige Verzinsungsart
237
 
60 andreas 238
	if (TpPars->effekt && (verzinsung == 1 || verzinsung == 3))
239
	   return 28;			// Effektivzinss. nur bei dekursiv möglich
240
 
53 andreas 241
	// Verzinsungsart mit Abschlußrhythmus gegenprüfen
242
 
243
	if (TpPars->verzart == 1 && TpPars->abschlry != 43 &&
244
		TpPars->abschlry != 46 && TpPars->abschlry != 52)
245
	   return 9;			// Verzinsung in Bezug auf Abschlußrhythmus ungültig
246
 
247
#ifdef _ZINSAENDERUNG
248
	// Zinssatzänderung mit Verzinsungsart gegenprüfen
249
 
250
	if (TpPars->ziaend && (verzinsung == 1 || verzinsung == 3))
251
	   return 23;			// Zinssatzänderung unter Antizipativ nicht möglich
252
#endif
253
	// Ratenart überprüfen
254
 
255
	if (TpPars->ratenart < 0 || TpPars->ratenart > 3)
256
	   return 13;			// ungültige Ratenart
257
 
258
	if (TpPars->ratenart == 0)
259
	   reh = 1;			// Kapitalraten
260
	else if (TpPars->ratenart == 1)
261
	   reh = 2;			// Pauschalraten
262
	else
263
	   reh = 0;			// Pauschalraten
264
 
265
	// Divisor setzen
266
 
267
	if (TpPars->tageb == 1 || TpPars->tageb == 2 || TpPars->tageb == 7 ||
268
	    TpPars->tageb == 8)
269
	   divisor = 36000.0;
270
	else
271
	   divisor = 36500.0;
272
 
273
	// Erstellen einer Datumstabelle
274
 
275
	if (verzinsung == 0 || verzinsung == 2)	// Dekursiv?
276
	{
277
	   if ((i = DekursivTable ()) != 0)
278
	      return i;
279
	}
280
	else					// Antizipativ
281
	{
282
	   if ((i = AntizipativTable ()) != 0)
283
	      return i;
284
	}
285
 
286
	// Berechnung der Rate
287
 
288
	a_ind = r_ind = 0;
289
 
290
	if (TpPars->fixrate == TRUE)	// Besteht eine Ratenvorgabe?
291
	{
292
	   TpPars->ergrate = rat = TpPars->rate;
293
	   return Ratenplan ();
294
	}
295
 
296
	// Erstellen eines Ratenplans
297
 
298
        GetRate (TpPars->rahmen, TpPars->ragab, TpPars->dvon);
299
 
300
	TpPars->ergrate = rat;
301
	return Ratenplan ();
302
}
303
 
304
#ifdef _ZINSAENDERUNG
305
 
306
int TRech::GetZiaend ()
307
{
308
QString hdir = QDir::homeDirPath ();
309
QFile tmpFile;
310
int fd;
311
struct stat sbuf;
312
ZIAEND Zi;
313
 
314
	// Plausibilitätsprüfung der eingebenen Daten
315
	hdir.append("/.zinsaend.dat");
316
	tmpFile.setName(hdir);
317
 
318
	if (tmpFile.open(IO_ReadWrite) == FALSE)
319
	{
320
	   KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
321
	   return 23;
322
	}
323
 
324
	fd = tmpFile.handle();
325
	fstat (fd, &sbuf);
326
 
327
	if (sbuf.st_size == 0L)
328
	{
329
	   tmpFile.close ();
330
	   return 0;
331
	}
332
 
333
	while (read (fd, &Zi, sizeof(ZIAEND)) == sizeof(ZIAEND))
334
	{
335
	   if (Zi.Datum <= TpPars->dvon)
336
	   {
337
	      tmpFile.close ();
338
	      return 24;
339
	   }
340
 
341
	   if (Zi.Datum >= TpPars->dbis)
342
	   {
343
	      tmpFile.close ();
344
	      return 25;
345
	   }
346
	}
347
 
348
	tmpFile.close ();
349
	return 0;
350
}
351
 
352
#endif
353
 
354
int TRech::DekursivTable ()
355
{
356
long tage;
60 andreas 357
int vday, day, mon, year, akt_day, akt_mon, iday, imon, iyear;
53 andreas 358
int at, am, aj;
359
BOOL abschluss, r_yet;
360
long lab;
60 andreas 361
QDate dat1, dat2;
53 andreas 362
 
363
	// Wurde eine fixe Rate vorgegeben und ein Enfälligkeitsdatum
364
	// angegeben, muß die letzte Einschränkung gleich dem
365
	// Endfälligkeitsdatum sein.
366
 
367
	if (TpPars->fixrate && TpPars->endfaell > 0L)
368
	   TpPars->dbis = TpPars->endfaell;
369
 
370
	// Wurde eine fixe Rate vorgegeben und keine letzte Einschränkung
371
	// und keine Endfälligkeit, werden 100 Jahre im voraus gesetzt.
372
	// Das ist die maximale Laufzeit.
373
 
374
	if (TpPars->dbis == 0L)
375
	{
60 andreas 376
	   QDate dt;
377
	   date_int(&day, &mon, &year, TpPars->ragab);
378
	   dt.setYMD(year, mon, day);
379
	   dt = dt.addYears(99);
380
	   TpPars->dbis = dt.year() * 10000L + dt.month() * 100L + dt.day();
53 andreas 381
	}
382
 
383
	// Wenn auf Ultimo gerechnet wird, muß der Tag der letzten
384
	// Einschränkung auf den letzten des Monats gesetzt werden.
385
	// Einzige Ausnahme: Verzinsungsart 7. Hier muß der Tag auf den
386
	// 1. eines Monats gesetzt werden.
387
 
388
	if (TpPars->ultimo)
389
	{
390
	   date_int (&day, &mon, &year, TpPars->dbis);
391
 
392
	   if (TpPars->verzart == 7)
393
	      day = 1;
394
	   else
395
	      day = MonLeiste[mon-1];
396
 
397
	   TpPars->dbis = make_date (day, mon, year);
398
	}
399
 
400
	// überprüfen der Laufzeit auf Grund der eingegebenen Daten
401
 
402
	if (TpPars->endfaell > 0L)
60 andreas 403
	{
404
	   QDate dt1, dt2;
405
	   date_int(&day, &mon, &year, TpPars->endfaell);
406
	   dt1.setYMD(year, mon, day);
407
	   date_int(&day, &mon, &year, TpPars->ragab);
408
	   dt2.setYMD(year, mon, day);
409
	   tage = dt2.daysTo(dt1);
410
//	   tage = DateToDay (TpPars->endfaell) - DateToDay (TpPars->ragab);
411
	}
53 andreas 412
	else
60 andreas 413
	{
414
	   QDate dt1, dt2;
415
	   date_int(&day, &mon, &year, TpPars->dbis);
416
	   dt1.setYMD(year, mon, day);
417
	   date_int(&day, &mon, &year, TpPars->ragab);
418
	   dt2.setYMD(year, mon, day);
419
	   tage = dt2.daysTo(dt1);
420
//	   tage = DateToDay (TpPars->dbis) - DateToDay (TpPars->ragab);
421
	}
53 andreas 422
 
423
	if (tage > 36524L)
424
	   return 14;			// Laufzeit über 100 Jahre
425
 
426
	if (TpPars->abschl == 0L)
427
	   TpPars->abschl = TpPars->ragab;
428
 
429
	date_int (&vday, &mon, &year, TpPars->dvon);
430
	date_int (&day, &mon, &year, TpPars->ragab);
431
	date_int (&at, &am, &aj, TpPars->abschl);
432
	akt_mon = mon - 1;
433
	a_ind = r_ind = 0;
434
	pos = 0;
435
	abschluss = FALSE;
436
	r_yet = FALSE;			// Nur TRUE wenn "a_dat" < TpPars->dvon
437
	lab = 0L;
438
 
439
	while (pos < tage && a_ind < 1200 && r_ind < 1200)
440
	{
441
	   set_feb (year);
442
 
443
	   // Abschlußdatum
444
 
445
	   if (TpPars->abschlry > 40)
446
	      akt_day = MonLeiste[akt_mon];
447
	   else
448
	   {
449
	      if (at > MonLeiste[akt_mon])
450
		 akt_day = MonLeiste[akt_mon];
451
	      else
452
		 akt_day = at;
453
	   }
454
 
455
	   a_dat = make_date (akt_day, akt_mon + 1, year);
456
 
457
	   if (test_abschl (akt_mon+1) && AbschlPlan[akt_mon] && a_dat > TpPars->ragab)
458
	   {
459
	      ab_dat[a_ind] = a_dat;
460
	      lab = a_dat;
461
 
462
	      if (a_dat < TpPars->dvon)
463
		 r_yet = TRUE;
464
 
465
	      if (!abschluss)
466
	      {
467
		 TpPars->abschl = TpPars->ragab;
468
		 abschluss = TRUE;
469
	      }
470
 
471
	      a_ind++;
472
	   }
473
 
474
	   // Einschränkungsdatum
475
 
476
	   if (TpPars->ultimo)
477
	      akt_day = MonLeiste[akt_mon];
478
	   else
479
           {
480
	      if (vday > MonLeiste[akt_mon])
481
		 akt_day = MonLeiste[akt_mon];
482
	      else
483
		 akt_day = vday;
484
	   }
485
 
486
	   r_dat = make_date (akt_day, akt_mon+1, year);
487
 
488
	   if ((TpPars->raplan[akt_mon] && r_dat >= TpPars->dvon &&
489
	       r_dat <= TpPars->dbis) || r_yet)
490
	   {
491
	      rat_dat[r_ind] = r_dat;
492
	      ldat = r_dat;
493
	      rat_anz[r_ind] = TpPars->raplan[akt_mon];
494
	      r_ind++;
495
	      r_yet = FALSE;
496
	   }
497
 
498
	   akt_mon++;
499
 
500
	   if (akt_mon >= 12)		// Jahreswechsel
501
	   {
502
	      akt_mon = 0;
503
	      year++;
504
	   }
505
 
60 andreas 506
	   date_int(&iday, &imon, &iyear, r_dat);
507
	   dat1.setYMD(iyear, imon, iday);
508
	   date_int(&iday, &imon, &iyear, TpPars->ragab);
509
	   dat2.setYMD(iyear, imon, iday);
510
	   pos = dat2.daysTo(dat1);
511
//	   pos = DateToDay (r_dat) - DateToDay (TpPars->ragab), r_dat, TpPars->ragab);
53 andreas 512
	}
513
 
60 andreas 514
	if (TpPars->effekt && (r_ind >= 1200 || a_ind >= 1200))
53 andreas 515
	   return 20;			// Rechenfehler
516
 
517
	if (lab != a_dat)
518
	{
519
	   ab_dat[a_ind] = TpPars->dbis;
520
	   a_ind++;
521
	}
522
 
523
	TpPars->dbis = ldat;
524
	max_abs = a_ind;
525
        max_rat = r_ind;
526
	return 0;
527
}
528
 
529
int TRech::AntizipativTable ()
530
{
531
long tage;
532
int vday, day, mon, year, akt_day, akt_mon;
533
int at, am, aj;
534
BOOL abschluss, r_yet;
535
long lab;
536
 
537
	// Wurde eine fixe Rate vorgegeben und ein Enfälligkeitsdatum
538
	// angegeben, muß die letzte Einschränkung gleich dem
539
	// Endfälligkeitsdatum sein.
540
 
541
	if (TpPars->fixrate && TpPars->endfaell > 0L)
542
	   TpPars->dbis = TpPars->endfaell;
543
 
544
	// Wurde eine fixe Rate vorgegeben und keine letzte Einschränkung
545
	// und keine Endfälligkeit, werden 100 Jahre im voraus gesetzt.
546
	// Das ist die maximale Laufzeit.
547
 
548
	if (TpPars->dbis == 0L)
549
	{
64 andreas 550
	   QDate dt;
551
	   date_int(&day, &mon, &year, TpPars->ragab);
552
	   dt.setYMD(year, mon, day);
553
	   dt = dt.addYears(99);		// 99 Jahre ist maximale Laufzeit
554
	   TpPars->dbis = dt.year() * 10000L + dt.month() * 100L + dt.day();
53 andreas 555
	}
556
 
557
	// Wenn auf Ultimo gerechnet wird, muß der Tag der letzten
558
	// Einschränkung auf den letzten des Monats gesetzt werden.
559
	// Einzige Ausnahme: Verzinsungsart 7. Hier muß der Tag auf den
560
	// 1. eines Monats gesetzt werden.
561
 
562
	if (TpPars->ultimo)
563
	{
564
	   if (TpPars->verzart == 3)
565
	      day = 1;
566
	   else
567
	   {
568
	      date_int (&day, &mon, &year, TpPars->dbis);
569
	      day = MonLeiste[mon-1];
570
	   }
571
 
572
	   TpPars->dbis = make_date (day, mon, year);
573
	}
574
	else
575
	{
576
	   date_int (&day, &mon, &year, TpPars->dbis);
577
	   day = 1;
578
	   TpPars->dbis = make_date (day, mon, year);
579
	}
580
 
581
	// überprüfen der Laufzeit auf Grund der eingegebenen Daten
582
 
583
	if (TpPars->endfaell > 0L)
584
	   tage = DateToDay (TpPars->endfaell) - DateToDay (TpPars->ragab);
585
	else
586
	   tage = DateToDay (TpPars->dbis) - DateToDay (TpPars->ragab);
587
 
588
	if (tage > 36525L)
589
	   return 14;			// Laufzeit �ber 100 Jahre
590
 
591
	if (TpPars->abschl == 0L)
592
	   TpPars->abschl = TpPars->ragab;
593
 
594
	date_int (&vday, &mon, &year, TpPars->dvon);
595
	date_int (&day, &mon, &year, TpPars->ragab);
596
	date_int (&at, &am, &aj, TpPars->abschl);
597
	akt_mon = mon - 1;
598
	a_ind = r_ind = 0;
599
	pos = 0;
600
	abschluss = FALSE;
601
	r_yet = FALSE;			// Nur TRUE wenn "a_dat" < TpPars->dvon
602
	lab = 0L;
603
 
604
	while (pos < tage)
605
	{
606
	   set_feb (year);
607
 
608
	   // Abschlußdatum
609
 
610
	   if (TpPars->abschlry > 40)
611
	      akt_day = MonLeiste[akt_mon];
612
	   else
613
	   {
614
	      if (at > MonLeiste[akt_mon])
615
		 akt_day = MonLeiste[akt_mon];
616
	      else
617
		 akt_day = at;
618
	   }
619
 
620
	   a_dat = make_date (akt_day, akt_mon + 1, year);
621
 
622
	   if (!abschluss)
623
	   {
624
	      ab_dat[a_ind] = TpPars->ragab;
625
	      lab = TpPars->ragab;
626
	      TpPars->abschl = TpPars->ragab;
627
	      abschluss = TRUE;
628
	      a_ind++;
629
           }
630
	   else if (test_abschl (akt_mon+1) && a_dat < TpPars->dbis)
631
	   {
632
	      a_dat = DateToDay (a_dat);
633
	      a_dat = DayToDate (a_dat + 1L);
634
	      ab_dat[a_ind] = a_dat;
635
	      lab = a_dat;
636
	      a_ind++;
637
           }
638
 
639
	   // Einschränkungsdatum
640
 
641
	   if (TpPars->ultimo)
642
	      akt_day = MonLeiste[akt_mon];
643
	   else
644
           {
645
	      if (vday > MonLeiste[akt_mon])
646
		 akt_day = MonLeiste[akt_mon];
647
	      else
648
		 akt_day = vday;
649
	   }
650
 
651
	   r_dat = make_date (akt_day, akt_mon+1, year);
652
 
653
	   if ((TpPars->raplan[akt_mon] && r_dat >= TpPars->dvon &&
654
	       r_dat <= TpPars->dbis) || r_yet)
655
	   {
656
	      rat_dat[r_ind] = r_dat;
657
	      ldat = r_dat;
658
	      rat_anz[r_ind] = TpPars->raplan[akt_mon];
659
	      r_ind++;
660
	      r_yet = FALSE;
661
	   }
662
 
663
	   akt_mon++;
664
 
665
	   if (akt_mon >= 12)		// Jahreswechsel
666
	   {
667
	      akt_mon = 0;
668
	      year++;
669
	   }
670
 
671
	   pos = DateToDay (r_dat) - DateToDay (TpPars->ragab);
672
	}
673
 
674
	if (lab != a_dat)
675
	{
676
	   ab_dat[a_ind] = TpPars->dbis;
677
	   a_ind++;
678
	}
679
 
680
	TpPars->dbis = ldat;
681
	max_abs = a_ind;
682
        max_rat = r_ind;
683
	return 0;
684
}
685
 
686
double TRech::runden (double zahl, int komma)
687
{
688
double vork, nachk;
689
long nk, nk1, splitter;
690
 
691
	if (zahl == 0.0)
692
	   return 0.0;
693
 
694
	nk = 0L;
695
	modf (zahl, &vork);
696
	nachk = zahl - vork;
697
 
698
        if (komma)
699
	   nk = (long)((double)(nachk * pow (10.0, (double)komma)));
700
 
701
	nk1 = (long)((double)(nachk * pow (10.0, (double)komma+1.0)));
702
	splitter = nk1 - (nk * 10L);
703
 
704
	if (splitter >= 5L)
705
	   nk++;
706
 
707
	if (komma == 0)
708
	{
709
	   if (splitter >= 5)
710
	      return vork+1.0;
711
 
712
	   return vork;
713
	}
714
 
715
	nachk = (double)nk / pow (10.0, (double)komma);
716
	vork += nachk;
717
	return vork;
718
}
719
 
720
BOOL TRech::test_abschl (int am)
721
{
722
BOOL t1,t2,t3,t4,t5,t6;
723
 
724
	t1 = (TpPars->abschlry == 1 || TpPars->abschlry == 41);
725
	t2 = ((TpPars->abschlry == 3 || TpPars->abschlry == 43) && (am == 3 || am == 6 || am == 9 || am == 12));
726
	t3 = ((TpPars->abschlry == 6 || TpPars->abschlry == 46) && (am == 6 || am == 12));
727
	t4 = ((TpPars->abschlry == 12 || TpPars->abschlry == 52) && am == 12);
728
	t5 = (TpPars->abschlry == 47 && (am == 3 || am == 9));
729
	t6 = (TpPars->abschlry == 48 && (am == 2 || am == 8));
730
 
731
	if (t1 || t2 || t3 || t4 || t5 || t6)
732
	   return TRUE;
733
 
734
	return FALSE;
735
}
736
 
737
long TRech::tageber (long date)
738
{
739
int tt_par, mm_par, jj_par;
740
 
741
	date_int (&tt_par, &mm_par, &jj_par, date);
742
 
743
	if (TpPars->tageb == 1 || TpPars->tageb == 4 || TpPars->tageb == 6)
744
	{
745
	   if (TpPars->abschlry > 40 || TpPars->ultimo)
746
	      if (tt_par >= 28 && mm_par == 2)
747
		 tt_par = 30;
748
 
749
	   if (tt_par > 30)
750
	      tg_par = (long)jj_par * 360L + (long)mm_par * 30L;
751
	   else
752
	      tg_par = (long)jj_par * 360L + ((long)mm_par - 1L) * 30L + (long)tt_par;
753
	}
754
	else
755
	   tg_par = DateToDay (date);
756
 
757
	return tg_par;
758
}
759
 
760
void TRech::vorrech ()
761
{
762
long tg;
763
 
764
	dat_par = ab_dat[a_ind];
765
	tg_par = tageber (dat_par);
766
	tg = tg_par - ab_tag;
767
	ab_tag = tg_par;
768
 
769
	if (verzinsung != 1)
770
	{
771
	   zi_kap = kap * (double)tg * TpPars->zssoll / divisor;
772
	   zi_rat = rat * (double)tg * TpPars->zssoll / divisor;
773
	}
774
	else
775
	{
776
	   zi_kap = kap * (double)tg * TpPars->zssoll / (divisor - (double)tg * TpPars->zssoll);
777
	   zi_rat = rat * (double)tg * TpPars->zssoll / (divisor - (double)tg * TpPars->zssoll);
778
	}
779
}
780
 
781
/* Einschränkung */
782
 
783
void TRech::einschr ()
784
{
785
long tg;
786
 
787
	rat = rat + (double)rat_anz[r_ind];
788
 
789
	if (TpPars->valuta == 0)
790
	{
791
	   dat_par = rat_dat[r_ind];
792
	   tg_par = tageber (dat_par);
793
	   tg = ab_tag - tg_par;
794
 
795
	   if (verzinsung == 1)
796
	      zi_rat = zi_rat + (double)rat_anz[r_ind] * (double)tg *
797
		       TpPars->zssoll / (divisor - (double)tg *
798
		       TpPars->zssoll);
799
	   else
800
	      zi_rat = zi_rat + (double)rat_anz[r_ind] * (double)tg *
801
		       TpPars->zssoll / divisor;
802
	}
803
 
804
	r_ind++;
805
}
806
 
807
/* Abschlußberechnung */
808
 
809
void TRech::abschlus ()
810
{
811
	switch (reh)
812
	{
813
	   case 0: kap += zi_kap;
814
		   rat += zi_rat;
815
	   break;
816
 
817
	   case 2: kap += (zi_kap + TpPars->spesen);
818
		   rat += zi_rat;
819
	   break;
820
	}
821
 
822
	a_ind++;
823
}
824
 
825
// Erstellen eines Ratenplans
826
 
827
double TRech::GetRate (double rahmen, long ragab, long dvon)
828
{
829
double ergrate;
830
 
831
	ab_tag = 0L;
832
	zi_rat = 0.0;
833
	zi_kap = 0.0;
834
	dat_par = 0L;
835
 
836
	if (rat_dat[r_ind] < dvon)
837
	   while (rat_dat[r_ind] < dvon && r_ind < max_rat)
838
	      r_ind++;
839
 
840
	dat_par = ragab;
841
	tageber (dat_par);
70 andreas 842
	kap = rahmen + TpPars->kosten;
53 andreas 843
	rat = 0.0;
844
	ab_tag = tg_par;
845
	vorrech ();
846
 
847
	while (r_ind < max_rat && a_ind < max_abs)
848
	{
849
	   if (rat_dat[r_ind] > ab_dat[a_ind])
850
	   {
851
	      abschlus ();
852
	      vorrech ();
853
	   }
854
	   else if (rat_dat[r_ind] < ab_dat[a_ind])
855
	      einschr ();
856
	   else if (verzinsung == 1 || verzinsung == 2)
857
	   {
858
	      abschlus ();
859
	      vorrech ();
860
	      einschr ();
861
	   }
862
	   else
863
	   {
864
	      einschr ();
865
	      abschlus ();
866
	      vorrech ();
867
	   }
868
	}
869
 
870
	if (verzinsung == 1 || verzinsung == 2)
871
	{
872
	   abschlus ();
873
	   einschr ();
874
	}
875
	else
876
	{
877
	   einschr ();
878
	   abschlus ();
879
	}
880
 
881
	if (rat != 0.0)
882
        {
883
           rat = (kap - TpPars->kapital) / rat;
884
	   ergrate = runden (rat, rund_fakt);
885
 
886
	   if (ergrate != rat && rund_fakt > 0)
887
              rat = ergrate + (1.0 / pow (10.0, (double)rund_fakt));
888
	   else if (rund_fakt == 0 && ergrate != rat)
889
	      rat = ergrate + 1.0;
890
	}
891
 
892
        return rat;
893
}
894
 
895
/************************************************************************
896
   Erstellung eines Tilgungsplans.
897
 
898
   Dieser wird in eine Datei ausgegeben. Die Datei besteht aus einem
899
   Kopf (Übergabestruktur) und einzelnen Datensätzen.
900
*************************************************************************/
901
 
902
// #$10100
903
int TRech::Ratenplan ()
904
{
905
	if (verzinsung == 0 || verzinsung == 2)
906
	   return DekursivPlan ();
907
 
908
	return AntizipativPlan ();
909
}
910
 
911
// #$10110
912
int TRech::DekursivPlan ()
913
{
914
QString hdir = QDir::homeDirPath ();
915
QFile tmpFile, zaf;
916
int fd, index, i;
917
int real_rat, Abzug;
60 andreas 918
long tg, effend;
53 andreas 919
double zins, tilg, zi1, zi2, kzi;
920
long offset;
921
BOOL stop;
922
#ifdef _ZINSAENDERUNG
923
   int fdZins;
924
   long zoff, LastAend;
925
   ZIAEND Zi;
926
   double aZins;
927
   struct stat sbuf;
928
#endif
929
 
930
	/* Planerstellung */
931
	hdir.append("/.date_tbl.dat");
932
	tmpFile.setName(hdir);
933
 
60 andreas 934
	if (!TpPars->effekt)
53 andreas 935
	{
60 andreas 936
	   if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
937
	   {
938
	      KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
939
	      return 1;
940
	   }
53 andreas 941
	}
60 andreas 942
	else
943
	{
944
	   if (tmpFile.open(IO_ReadOnly) == FALSE)
945
	   {
946
	      KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
947
	      return 1;
948
	   }
949
	}
53 andreas 950
 
951
	fd = tmpFile.handle();
952
#ifdef _ZINSAENDERUNG
953
	// Wenn eine Zinssatzänderung gewünscht wurde, muß die Änderungs-
954
	// datei geöffnet werden.
955
 
956
	zoff = 0L;
957
        LastAend = 0L;		// Beinhaltet Datum der letzten Zinssatzänderung
958
	aZins = 0.0;
959
	memset (&Zi, 0, sizeof(ZIAEND));
960
 
961
	if (TpPars->ziaend)
962
        {
963
           hdir = QDir::homeDirPath ();
964
           hdir.append("/.zinsaend.dat");
965
           zaf.setName(hdir);
966
           fdZins = -1;
967
 
968
           if (zaf.open(IO_ReadOnly) == FALSE)
969
	      TpPars->ziaend = FALSE;
970
	   else
971
           {
972
	      fdZins = zaf.handle();
973
	      fstat (fdZins, &sbuf);
974
 
975
	      if (sbuf.st_size == 0L)
976
		 TpPars->ziaend = FALSE;
977
	      else
978
              {
979
		 read (fdZins, &Zi, sizeof(ZIAEND));
980
                 zoff += (long)sizeof(ZIAEND);
981
              }
982
	   }
983
 
984
	   if (!TpPars->ziaend && fdZins != -1)
985
              zaf.close ();
986
	}
987
#endif
988
 
989
	offset = 0L;
990
	index = max_abs + max_rat;
991
 
992
	/* Ausgangsdaten schreiben */
60 andreas 993
	if (!TpPars->effekt)
994
	{
995
	   write (fd, TpPars, sizeof (TPPARS));
996
	   offset += (long)sizeof (TPPARS);
997
	}
53 andreas 998
 
999
	/* Initialisierung der Schleife */
1000
 
1001
	a_ind = r_ind = 0;
1002
	kap = TpPars->rahmen;
1003
	zins = 0.0;
1004
	TpPars->gesamt = kap;
1005
	tilg = kzi = 0.0;
1006
	tg = 0;
1007
	TpPars->abschl = ab_dat[0];
1008
	stop = FALSE;			// TRUE wenn Laufzeitende bei Ratenvorgabe
1009
	real_rat = max_rat;
1010
        Abzug = 0;			// wird nur bei Ratenvorgabe verwendet
1011
 
60 andreas 1012
	if (TpPars->effekt)
1013
	   effend = TpPars->dvon + 10000L;	// 1 Jahr für Effektivzinsberechnung
1014
	else
1015
	   effend = 0L;
1016
 
70 andreas 1017
	/* Spesen dürfen nur einmal bei der Auszahlung auf das Kapital
1018
	 * aufgeschlagen werden.
1019
	 */
1020
	if (!TpPars->effekt)
1021
	{
1022
	   DTable.datum = TpPars->ragab;
1023
	   DTable.kz = 'U';		// Auszahlung
1024
	   DTable.kapital = kap;
1025
	   DTable.tilg = 0.0;
1026
	   DTable.rate = 0.0;
1027
	   DTable.zinsen = TpPars->kosten;
1028
	   DTable.rkapi = kap + TpPars->kosten;
1029
	   kap += TpPars->kosten;
1030
 
1031
	   write (fd, &DTable, sizeof (DTABLE));
1032
	   offset += (long)sizeof (DTABLE);
1033
	}
1034
 
53 andreas 1035
	/* Schleife zur Berechnung der Gesamtbelastung (Dekursiv) */
70 andreas 1036
 
53 andreas 1037
	for (i = 0; i < index; i++)
1038
	{
1039
#ifdef _ZINSAENDERUNG
1040
	   // Ist eine Zinssatzänderung gewünscht?
1041
 
1042
	   if ((Zi.Datum < rat_dat[r_ind-1] || Zi.Datum < ab_dat[a_ind]) &&
1043
	       zoff <= sbuf.st_size && TpPars->ziaend)
1044
	   {
1045
	      DTable.datum = Zi.Datum;
1046
	      DTable.kz = 'Z';
1047
	      DTable.kapital = kap;
1048
	      index++;
1049
 
1050
	      if (a_ind > 0)
1051
	      {
1052
		 if (ab_dat[a_ind-1] < Zi.Datum)
1053
		    ldat = ab_dat[a_ind-1];
1054
		 else
1055
		    ldat = Zi.Datum;
1056
 
1057
		 tg = tageber (Zi.Datum) - tageber (ldat);
1058
	      }
1059
	      else
1060
	         tg = tageber (Zi.Datum) - tageber (TpPars->ragab);
1061
 
1062
	      aZins = kap * (double)tg * TpPars->zssoll / divisor;
1063
	      kap += runden (aZins, rund_fakt);
1064
              LastAend = Zi.Datum;
64 andreas 1065
	      DTable.rate = Zi.Zins;
53 andreas 1066
	      DekZiAend (fdZins, &zoff, sbuf.st_size, &Zi);
1067
	      kap = DTable.kapital;
1068
	   }
1069
	   else if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1070
#else
1071
	   if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1072
#endif
1073
	   {
1074
	      DTable.datum = rat_dat[r_ind];
1075
	      DTable.kz = 'R';
1076
	      DTable.kapital = runden (kap, rund_fakt);
1077
 
1078
	      if (r_ind > 0)
1079
	      {
1080
		 if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1081
		    ldat = ab_dat[a_ind-1];
1082
		 else
1083
		    ldat = rat_dat[r_ind-1];
1084
#ifdef _ZINSAENDERUNG
1085
		 if (LastAend && LastAend > ldat)
1086
		    ldat = LastAend;
1087
#endif
1088
		 tg = tageber (rat_dat[r_ind]) - tageber (ldat);
1089
	      }
1090
	      else
1091
	         tg = tageber (rat_dat[r_ind]) - tageber (TpPars->ragab);
1092
 
1093
	      zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1094
#ifdef _ZINSAENDERUNG
1095
	      if (LastAend)
1096
	      {
1097
		 LastAend = 0L;
1098
		 zi1 += aZins;
1099
	      }
1100
#endif
1101
              zi1 = runden (zi1, rund_fakt);
1102
	      zins += zi1;
1103
	      kzi += zi1;
1104
 
1105
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1106
	      {
1107
	         if (!stop && r_ind > 0 && DTable.rkapi < rat)
1108
	         {
1109
	            max_rat = r_ind + 1;
1110
	            max_abs = a_ind + 1;
1111
	            real_rat = max_rat - Abzug;
1112
	            ab_dat[a_ind] = rat_dat[r_ind];
1113
	            index = max_rat + max_abs;
1114
	            stop = TRUE;
1115
	         }
1116
	      }
1117
 
1118
	      if (r_ind == (max_rat - 1)) 		/* letzte Rate */
1119
	      {
1120
		 if (reh != 1)
1121
		 {
1122
		    zi2 = (kap < rat) ? rat - kap : kap - rat;
1123
		    zi2 = rat - zi2 + zins;
1124
//	            zi2 = rat + ((TpPars->gesamt + zins) - (rat * (LFLOAT)real_rat));
1125
		 }
1126
	         else
1127
	            zi2 = rat - ((rat * (double)real_rat) - TpPars->rahmen);
1128
 
1129
	         rat = zi2 + TpPars->spesen;
1130
	      }
1131
 
1132
	      TpPars->lrate = rat;
1133
	      tilg += rat;				/* Tilgung */
1134
 
1135
	      if (DTable.datum >= TpPars->dvon)		/* Restkapital */
1136
	         kap -= rat;
1137
 
1138
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1139
	      DTable.tilg = 0.0;
1140
	      DTable.rate = rat;
1141
	      DTable.zinsen = zi1;
1142
	      r_ind++;
1143
	   }
1144
	   else
1145
	   {
1146
	      DTable.datum = ab_dat[a_ind];
1147
	      DTable.kz = 'A';
1148
 
1149
	      if (r_ind > 0 && rat_dat[r_ind-1] <= ab_dat[0])
1150
	         DTable.kapital = TpPars->rahmen;
1151
	      else
1152
	         DTable.kapital = (kap >= 0.0) ? kap : 0.0;
1153
 
1154
	      kap += TpPars->spesen;
1155
	      DTable.rate = 0.0;
1156
 
1157
	      if (r_ind > 0)
1158
              {
1159
	         if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1160
	            ldat = ab_dat[a_ind-1];
1161
	         else
1162
	            ldat = rat_dat[r_ind-1];
1163
#ifdef _ZINSAENDERUNG
1164
		 if (LastAend && LastAend > ldat)
1165
		    LastAend = 0L;
1166
#endif
1167
		 tg = tageber (ab_dat[a_ind]) - tageber (ldat);
1168
 
1169
	         if (tg > 0)
1170
                 {
1171
		    zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1172
#ifdef _ZINSAENDERUNG
1173
	            if (LastAend)
1174
	            { 
1175
		       LastAend = 0L;
1176
		       zi1 += aZins;
1177
	            }
1178
#endif
1179
		    zins += zi1;
1180
	            kzi += runden (zi1, rund_fakt);
1181
	            zins = runden (zins, rund_fakt);
1182
		 }
1183
#ifdef _ZINSAENDERUNG
1184
		 else if (LastAend)
1185
		    LastAend = 0L;
1186
#endif
1187
	      }
1188
 
1189
	      DTable.zinsen = zins;
1190
	      TpPars->gesamt += zins + TpPars->spesen;	/* Gesamtbelastung */
1191
 
1192
	      if (reh != 2)
1193
	         tilg -= zins;      		/* Tilgung - Zinsen */
1194
 
1195
	      if (DTable.datum < TpPars->dvon)
1196
	         DTable.tilg = 0.0;
1197
	      else
1198
	         DTable.tilg = tilg;
1199
 
1200
	      if (reh != 1)
1201
	         kap += zins;
1202
 
1203
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1204
	      zins = 0.0;
1205
	      tilg = 0.0;
1206
	      a_ind++;
1207
	   } /* end if */
1208
 
1209
	   if (DTable.datum < TpPars->dvon && DTable.kz == 'R')
1210
	   {
1211
              if (TpPars->fixrate)
1212
	         Abzug++;
1213
	      else
1214
	         real_rat--;
1215
 
1216
	      continue;
1217
	   }
1218
 
60 andreas 1219
	   if (!TpPars->effekt)
1220
	   {
1221
	      write (fd, &DTable, sizeof (DTABLE));
1222
	      offset += (long)sizeof (DTABLE);
1223
	   }
1224
	   else if (DTable.datum > effend)
1225
	      break;
53 andreas 1226
	} /* end for */
1227
 
1228
	if (TpPars->fixrate == TRUE)
1229
	   TpPars->dbis = rat_dat[r_ind-1];
1230
 
1231
	TpPars->anzraten = real_rat;
1232
	DTable.datum = (long)real_rat;		/* Laufzeit */
1233
	DTable.kz = 'E';			/* Ergebnis */
1234
	DTable.kapital = TpPars->rahmen;
1235
	DTable.tilg = TpPars->gesamt;
1236
	DTable.rate = 0.0;
1237
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1238
 
1239
	if (TpPars->zuschprz > 0.0)
1240
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1241
	else
1242
	   TpPars->zuschuss = 0.0;
1243
 
1244
	DTable.zinsen = TpPars->gesamt - TpPars->rahmen;
1245
	TpPars->gesamt -= TpPars->zuschuss;
1246
 
1247
	// Annuitätenzuschuß berechnen und anzeigen
1248
 
1249
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1250
	{
1251
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1252
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1253
	   TpPars->antotal -= TpPars->zuschuss;
1254
	}
1255
	else
1256
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1257
 
1258
	DTable.rkapi = TpPars->lrate;
60 andreas 1259
 
1260
	if (!TpPars->effekt)
1261
	   write (fd, &DTable, sizeof (DTABLE));
53 andreas 1262
#ifdef _ZINSAENDERUNG
64 andreas 1263
//	if (TpPars->gewicht > 0.0)
1264
//	   TpPars->zssoll = TpPars->gewicht;
53 andreas 1265
 
1266
	zaf.close();
1267
#endif
64 andreas 1268
	tmpFile.flush();
1269
 
60 andreas 1270
	if (!TpPars->effekt)
1271
	{
1272
	   lseek (fd, 0L, 0);
1273
	   write (fd, TpPars, sizeof (TPPARS));
1274
	}
64 andreas 1275
	else
1276
	{
1277
	   // Zinsen nach einem Jahr ermitteln
1278
	   tmpFile.flush();
1279
	   lseek (fd, (long)sizeof(TPPARS), 0);
1280
	   zins = 0.0;
60 andreas 1281
 
64 andreas 1282
	   while (read (fd, &DTable, sizeof(DTABLE)) >= sizeof(DTABLE))
1283
	   {
1284
	      if (DTable.kz == 'R' && DTable.datum >= effend)
1285
		 break;
1286
 
1287
	      if (DTable.kz == 'R')
1288
		 zins += DTable.zinsen;
1289
	   }
1290
 
1291
	   TpPars->effformel = 100.0 - (100.0 / TpPars->ezins * zins);
1292
	}
1293
 
53 andreas 1294
	tmpFile.close ();
1295
	return 0;
1296
}
1297
 
1298
#ifdef _ZINSAENDERUNG
1299
void TRech::DekZiAend (int fdZins, long *zoff, long size, ZIAEND *Zi)
1300
{
1301
int old_rind, old_aind;
1302
long datum;
1303
double old_kap;
1304
 
1305
	TpPars->gewicht = TpPars->zssoll;
1306
	TpPars->zssoll = Zi->Zins;
1307
 
1308
	if (Zi->Rate)
1309
        {
1310
	   old_kap = kap;
1311
	   old_rind = r_ind;
1312
	   old_aind = a_ind;
1313
 
1314
	   if (rat_dat[r_ind] > ab_dat[a_ind])
1315
	      datum = ab_dat[a_ind];
1316
	   else
1317
	      datum = rat_dat[r_ind];
1318
 
1319
	   GetRate (kap, Zi->Datum, datum);
1320
	   kap = old_kap;
1321
	   r_ind = old_rind;
1322
	   a_ind = old_aind;
1323
	   TpPars->ergrate = rat;
1324
	}
1325
	else if (Zi->FixRate)
1326
        {
1327
	   rat = Zi->NewRate;
1328
	   TpPars->ergrate = rat;
1329
	}
1330
 
1331
	if (*zoff < size)
1332
	   read (fdZins, Zi, sizeof(ZIAEND));
1333
	else
1334
	   close (fdZins);
1335
 
1336
        *zoff += (long)sizeof(ZIAEND);
1337
}
1338
 
1339
#endif
1340
int TRech::AntizipativPlan ()
1341
{
1342
QString hdir = QDir::homeDirPath ();
1343
QFile tmpFile;
1344
int fd, index, i;
1345
int real_rat, Abzug;
1346
long t1, t2, r_dat, old_par, r_tg, a_tg;
1347
double zins, tilg, kzi, sumrat;
1348
long offset, loff;
1349
BOOL stop;
1350
DTABLE old_tab;
1351
 
1352
	/* Planerstellung */
1353
	hdir.append("/.date_tbl.dat");
1354
	tmpFile.setName(hdir);
1355
 
1356
	if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
1357
	{
1358
	   KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
1359
	   return 1;
1360
	}
1361
 
1362
 
1363
	fd = tmpFile.handle();
1364
	offset = 0L;
1365
	index = max_abs - 1 + max_rat;
1366
 
1367
	/* Ausgangsdaten schreiben */
1368
	write (fd, TpPars, sizeof (TPPARS));
1369
	offset += (long)sizeof (TPPARS);
1370
 
1371
	/* Initialisierung der Schleife */
1372
 
1373
	a_ind = r_ind = 0;
1374
	kap = TpPars->rahmen;
1375
	zins = 0.0;
1376
	TpPars->gesamt = kap;
1377
	tilg = kzi = 0.0;
1378
	TpPars->abschl = ab_dat[0];
1379
	stop = FALSE;			// TRUE wenn Laufzeitende bei Ratenvorgabe
1380
	real_rat = max_rat;
1381
        Abzug = 0;			// wird nur bei Ratenvorgabe verwendet
1382
 
1383
	/* Schleife zur Berechnung der Gesamtbelastung (Antizipativ) */
1384
 
1385
	a_ind++;			/* Start bei 1! */
1386
	ab_tag = tageber (ab_dat[a_ind]);
1387
	tageber (TpPars->ragab);
1388
	tg_alt = tg_par;
1389
	sumrat = 0.0;
1390
	DTable.rkapi = runden (kap, rund_fakt);
1391
	DTable.kapital = runden (kap, rund_fakt);
1392
	loff = offset;
1393
	old_tab.datum = ab_dat[0];
1394
	old_tab.kz = 'A';
1395
	old_tab.kapital = TpPars->rahmen;
1396
	write (fd, &old_tab, sizeof (DTABLE));	/* Platzhalter */
1397
	offset += (long)sizeof (DTABLE);
1398
	r_dat = 0L;
1399
 
1400
	for (i = 0; i < index-1; i++)
1401
	{
1402
	   if ((rat_dat[r_ind] < ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1403
	   {
1404
	      DTable.datum = rat_dat[r_ind];
1405
	      DTable.kz = 'R';
1406
 
1407
	      tageber (rat_dat[r_ind+1]);
1408
	      t1 = ab_tag - tg_alt;
1409
	      t2 = ab_tag - tg_par;
1410
 
1411
	      if (t2 < 0L)
1412
		 t2 = 0L;
1413
 
1414
              // Berechnung der letzten Rate
1415
	      if (rat > (DTable.rkapi - TpPars->kapital))
1416
	         rat = runden (DTable.rkapi - TpPars->kapital, rund_fakt);
1417
 
1418
	      sumrat += rat;
1419
 
1420
//              if (reh == 1)		// Kapitalraten
1421
	         kap -= rat;
1422
 
1423
	      if (reh != 1)		// Pauschalraten
1424
	      {
1425
	         kzi = kap * TpPars->zssoll * ((double)t1 *
1426
	               (divisor - (double)t2 * TpPars->zssoll) -
1427
		       (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1428
		       ((divisor - (double)t1 * TpPars->zssoll) *
1429
		       (divisor - (double)t2 * TpPars->zssoll));
1430
	      }
1431
	      else			// Kapitalraten
1432
//	         kzi = kap * (tg_par - tg_alt) * TpPars->zssoll / divisor;
1433
		 kzi = kap * (t1 - t2) * TpPars->zssoll / divisor;
1434
 
1435
	      kzi = runden (kzi, rund_fakt);
1436
	      tg_alt = tg_par;
1437
	      zins += kzi;
1438
 
1439
              if (reh == 1)		// Kapitalraten
1440
		 DTable.rkapi = DTable.kapital - sumrat;
1441
	      else			// Pauschalraten
1442
		 DTable.rkapi = DTable.kapital + zins - sumrat;
1443
 
1444
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1445
	      {
1446
		 if (!stop && r_ind > 0 && DTable.rkapi < rat)
1447
	         {
1448
	            max_rat = r_ind + 1;
1449
	            max_abs = a_ind + 1;
1450
	            ab_dat[a_ind] = rat_dat[r_ind];
1451
                    real_rat = max_rat - Abzug;
1452
	            index = max_rat + max_abs;
1453
	            stop = TRUE;
1454
	         }
1455
	      }
1456
 
1457
              if (reh == 1)		// Kapitalraten
1458
		 DTable.tilg = rat;
1459
	      else                 	// Pauschalraten
1460
		 DTable.tilg = rat - kzi;
1461
 
1462
	      tilg += DTable.tilg;
1463
	      TpPars->lrate = rat;
1464
 
1465
	      DTable.rate = rat;
1466
	      DTable.zinsen = kzi;
1467
	      r_ind++;
1468
	   }
1469
	   else			/* Abschluß */
1470
	   {
1471
	      DTable.datum = ab_dat[a_ind];
1472
 
1473
	      if (i == (index-2))
1474
	      {
1475
		 DTable.kz = 'R';
1476
		 max_rat++;
1477
//		 TpPars->lrate = DTable.kapital - tilg;
1478
	      }
1479
	      else
1480
	         DTable.kz = 'A';
1481
 
1482
	      if (a_ind > 1)
1483
              {
1484
                 old_par = tg_par; 
1485
 
1486
		 if (reh == 1)			// Kapitalraten
1487
                 {
1488
		    r_tg = tageber (r_dat);
1489
                    a_tg = tageber (ab_dat[a_ind-1]);
1490
		    t1 = r_tg - a_tg;
1491
		    t2 = 0L;
1492
		 }
1493
		 else
1494
		 {
1495
		    a_tg = tageber (ab_dat[a_ind]);
1496
		    tageber (ab_dat[a_ind-1]);
1497
		    t1 = a_tg - tg_par;
1498
		    tageber (r_dat);
1499
		    t2 = ab_tag - tg_par;
1500
		 }
1501
 
1502
		 tg_par = old_par;
1503
 
1504
		 if (reh != 1)			// Pauschalraten
1505
                 {
1506
		    kzi = DTable.kapital * TpPars->zssoll * ((double)t1 *
1507
	                  (divisor - (double)t2 * TpPars->zssoll) -
1508
		          (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1509
		          ((divisor - (double)t1 * TpPars->zssoll) *
1510
			  (divisor - (double)t2 * TpPars->zssoll));
1511
                 }
1512
		 else                           // Kapitalraten
1513
		    kzi = DTable.kapital * t1 * TpPars->zssoll / divisor;
1514
 
1515
		 kzi = runden (kzi, rund_fakt);
1516
		 zins += kzi;
1517
 
1518
		 if (reh != 1)
1519
		 {
1520
                    tilg -= kzi;
1521
		    DTable.rkapi = DTable.kapital - tilg;
1522
                 }
1523
	      }
1524
 
1525
	      DTable.kapital -= tilg;
1526
	      r_dat = rat_dat[r_ind];
1527
 
1528
	      if (i == (index - 2))
1529
	      {
1530
	         DTable.rate = DTable.kapital;
1531
		 TpPars->lrate = DTable.rate;
1532
	         DTable.zinsen = 0.0;
1533
	         DTable.tilg = DTable.kapital;
1534
	         DTable.rkapi = 0.0;
1535
	      }
1536
	      else
1537
	      {
1538
	         DTable.rate = runden (sumrat, rund_fakt);
1539
	         DTable.zinsen = zins;
1540
	         DTable.tilg = tilg;
1541
	      }
1542
 
1543
	      TpPars->gesamt += zins;		/* Gesamtbelastung */
1544
 
1545
	      tmpFile.flush();
1546
	      lseek (fd, loff, 0);
1547
	      /* Füllen der Struktur */
1548
	      old_tab.tilg = tilg;
1549
	      old_tab.rate = 0.0;
1550
	      old_tab.zinsen = zins;
1551
 
1552
              if (reh == 1)
1553
		 old_tab.rkapi = old_tab.kapital;
1554
              else
1555
		 old_tab.rkapi = old_tab.kapital + zins;
1556
 
1557
	      write (fd, &old_tab, sizeof (DTABLE));
1558
	      old_tab.kapital = DTable.kapital;
1559
	      old_tab.datum = DTable.datum;
1560
	      lseek (fd, offset, 0);
1561
	      loff = offset;
1562
 
1563
//              if (reh == 1)			// Kapitalraten
1564
		 kap = DTable.kapital;
1565
 
1566
	      zins = 0.0;
1567
	      tilg = 0.0;
1568
	      sumrat = 0.0;
1569
	      a_ind++;
1570
	      ab_tag = tageber (ab_dat[a_ind]);
1571
	   } /* end if */
1572
 
1573
	   if (DTable.datum <= ab_dat[0] && DTable.datum < TpPars->dvon &&
1574
	       DTable.kz == 'R')
1575
	   {
1576
	      if (TpPars->fixrate)
1577
		 Abzug++;
1578
	      else
1579
	         real_rat--;
1580
 
1581
	      continue;
1582
           }
1583
 
1584
	   write (fd, &DTable, sizeof (DTABLE));
1585
	   offset += (long)sizeof (DTABLE);
1586
	} /* end for */
1587
 
1588
	if (TpPars->fixrate == TRUE)
1589
	   TpPars->dbis = rat_dat[r_ind-1];
1590
 
1591
	TpPars->anzraten = real_rat;
1592
	DTable.datum = (long)real_rat;		/* Laufzeit */
1593
	DTable.kz = 'E';			/* Ergebnis */
1594
	DTable.kapital = TpPars->rahmen;
1595
	DTable.tilg = TpPars->gesamt;
1596
	DTable.rate = 0.0;
1597
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1598
 
1599
	if (TpPars->zuschprz > 0.0)
1600
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1601
	else
1602
	   TpPars->zuschuss = 0.0;
1603
 
1604
	DTable.zinsen = kzi;
1605
	TpPars->gesamt -= TpPars->zuschuss;
1606
 
1607
	// Annuitätenzuschuß berechnen und anzeigen
1608
 
1609
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1610
	{
1611
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1612
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1613
	   TpPars->antotal -= TpPars->zuschuss;
1614
	}
1615
	else
1616
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1617
 
1618
	DTable.rkapi = TpPars->lrate;
1619
	write (fd, &DTable, sizeof (DTABLE));
1620
	tmpFile.flush();
1621
	lseek (fd, 0L, 0);
1622
	write (fd, TpPars, sizeof (TPPARS));
1623
	tmpFile.close ();
1624
	return 0;
1625
}
1626
 
1627
void TRech::init_global_vars ()
1628
{
1629
int i;
1630
 
1631
	ab_tag = 0L;
1632
	zi_rat = 0.0;
1633
	zi_kap = 0.0;
1634
	dat_par = 0L;
70 andreas 1635
	reh = 0;
1636
	divisor = 0.0;
1637
	a_ind = 0;
1638
	r_ind = 0;
1639
	max_abs = max_rat = 0;
1640
	pos = 0L;
1641
	a_dat = 0L;
1642
	tg_par = tg_alt = 0L;
1643
	r_dat = 0L;
1644
	ldat = 0L;
1645
	rat = kap = 0.0;
53 andreas 1646
 
1647
	for (i = 0; i < 1200; i++)
1648
	{
1649
	   rat_dat[i] = 0L;
1650
	   ab_dat[i] = 0L;
1651
	   rat_anz[i] = 0L;
1652
	}
1653
}