Subversion Repositories public

Rev

Rev 70 | 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)
71 andreas 906
	{
907
	   if (TpPars->effekt)
908
	   {
909
	   int i = 0;
910
	   int ret;
911
 
912
	      TpPars->effformel = TpPars->zssoll;
913
 
914
	      while (i < 10000 && (ret = DekursivPlan ()) == -2)
915
	      {
916
		 TpPars->zssoll = TpPars->effformel;
917
		 i++;
918
	      }
919
 
920
	      if (ret != -2)
921
		 return ret;
922
fprintf (stderr, "bzins: %.2f, ezins: %.2f\n", TpPars->gewicht, TpPars->ezins);
923
	      return 0;
924
	   }
925
 
53 andreas 926
	   return DekursivPlan ();
71 andreas 927
	}
53 andreas 928
 
929
	return AntizipativPlan ();
930
}
931
 
932
// #$10110
933
int TRech::DekursivPlan ()
934
{
935
QString hdir = QDir::homeDirPath ();
936
QFile tmpFile, zaf;
937
int fd, index, i;
938
int real_rat, Abzug;
60 andreas 939
long tg, effend;
53 andreas 940
double zins, tilg, zi1, zi2, kzi;
941
long offset;
942
BOOL stop;
943
#ifdef _ZINSAENDERUNG
944
   int fdZins;
945
   long zoff, LastAend;
946
   ZIAEND Zi;
947
   double aZins;
948
   struct stat sbuf;
949
#endif
950
 
951
	/* Planerstellung */
952
	hdir.append("/.date_tbl.dat");
953
	tmpFile.setName(hdir);
954
 
60 andreas 955
	if (!TpPars->effekt)
53 andreas 956
	{
60 andreas 957
	   if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
958
	   {
959
	      KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
960
	      return 1;
961
	   }
53 andreas 962
	}
60 andreas 963
	else
964
	{
965
	   if (tmpFile.open(IO_ReadOnly) == FALSE)
966
	   {
967
	      KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
968
	      return 1;
969
	   }
970
	}
53 andreas 971
 
972
	fd = tmpFile.handle();
973
#ifdef _ZINSAENDERUNG
974
	// Wenn eine Zinssatzänderung gewünscht wurde, muß die Änderungs-
975
	// datei geöffnet werden.
976
 
977
	zoff = 0L;
978
        LastAend = 0L;		// Beinhaltet Datum der letzten Zinssatzänderung
979
	aZins = 0.0;
980
	memset (&Zi, 0, sizeof(ZIAEND));
981
 
982
	if (TpPars->ziaend)
983
        {
984
           hdir = QDir::homeDirPath ();
985
           hdir.append("/.zinsaend.dat");
986
           zaf.setName(hdir);
987
           fdZins = -1;
988
 
989
           if (zaf.open(IO_ReadOnly) == FALSE)
990
	      TpPars->ziaend = FALSE;
991
	   else
992
           {
993
	      fdZins = zaf.handle();
994
	      fstat (fdZins, &sbuf);
995
 
996
	      if (sbuf.st_size == 0L)
997
		 TpPars->ziaend = FALSE;
998
	      else
999
              {
1000
		 read (fdZins, &Zi, sizeof(ZIAEND));
1001
                 zoff += (long)sizeof(ZIAEND);
1002
              }
1003
	   }
1004
 
1005
	   if (!TpPars->ziaend && fdZins != -1)
1006
              zaf.close ();
1007
	}
1008
#endif
1009
 
1010
	offset = 0L;
1011
	index = max_abs + max_rat;
1012
 
1013
	/* Ausgangsdaten schreiben */
60 andreas 1014
	if (!TpPars->effekt)
1015
	{
1016
	   write (fd, TpPars, sizeof (TPPARS));
1017
	   offset += (long)sizeof (TPPARS);
1018
	}
53 andreas 1019
 
1020
	/* Initialisierung der Schleife */
1021
 
1022
	a_ind = r_ind = 0;
1023
	kap = TpPars->rahmen;
1024
	zins = 0.0;
1025
	TpPars->gesamt = kap;
1026
	tilg = kzi = 0.0;
1027
	tg = 0;
1028
	TpPars->abschl = ab_dat[0];
1029
	stop = FALSE;			// TRUE wenn Laufzeitende bei Ratenvorgabe
1030
	real_rat = max_rat;
1031
        Abzug = 0;			// wird nur bei Ratenvorgabe verwendet
1032
 
60 andreas 1033
	if (TpPars->effekt)
1034
	   effend = TpPars->dvon + 10000L;	// 1 Jahr für Effektivzinsberechnung
1035
	else
1036
	   effend = 0L;
1037
 
70 andreas 1038
	/* Spesen dürfen nur einmal bei der Auszahlung auf das Kapital
1039
	 * aufgeschlagen werden.
1040
	 */
1041
	if (!TpPars->effekt)
1042
	{
1043
	   DTable.datum = TpPars->ragab;
1044
	   DTable.kz = 'U';		// Auszahlung
1045
	   DTable.kapital = kap;
1046
	   DTable.tilg = 0.0;
1047
	   DTable.rate = 0.0;
1048
	   DTable.zinsen = TpPars->kosten;
1049
	   DTable.rkapi = kap + TpPars->kosten;
1050
	   kap += TpPars->kosten;
1051
 
1052
	   write (fd, &DTable, sizeof (DTABLE));
1053
	   offset += (long)sizeof (DTABLE);
1054
	}
1055
 
53 andreas 1056
	/* Schleife zur Berechnung der Gesamtbelastung (Dekursiv) */
70 andreas 1057
 
53 andreas 1058
	for (i = 0; i < index; i++)
1059
	{
1060
#ifdef _ZINSAENDERUNG
1061
	   // Ist eine Zinssatzänderung gewünscht?
1062
 
1063
	   if ((Zi.Datum < rat_dat[r_ind-1] || Zi.Datum < ab_dat[a_ind]) &&
1064
	       zoff <= sbuf.st_size && TpPars->ziaend)
1065
	   {
1066
	      DTable.datum = Zi.Datum;
1067
	      DTable.kz = 'Z';
1068
	      DTable.kapital = kap;
1069
	      index++;
1070
 
1071
	      if (a_ind > 0)
1072
	      {
1073
		 if (ab_dat[a_ind-1] < Zi.Datum)
1074
		    ldat = ab_dat[a_ind-1];
1075
		 else
1076
		    ldat = Zi.Datum;
1077
 
1078
		 tg = tageber (Zi.Datum) - tageber (ldat);
1079
	      }
1080
	      else
1081
	         tg = tageber (Zi.Datum) - tageber (TpPars->ragab);
1082
 
1083
	      aZins = kap * (double)tg * TpPars->zssoll / divisor;
1084
	      kap += runden (aZins, rund_fakt);
1085
              LastAend = Zi.Datum;
64 andreas 1086
	      DTable.rate = Zi.Zins;
53 andreas 1087
	      DekZiAend (fdZins, &zoff, sbuf.st_size, &Zi);
1088
	      kap = DTable.kapital;
1089
	   }
1090
	   else if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1091
#else
1092
	   if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1093
#endif
1094
	   {
1095
	      DTable.datum = rat_dat[r_ind];
1096
	      DTable.kz = 'R';
1097
	      DTable.kapital = runden (kap, rund_fakt);
1098
 
1099
	      if (r_ind > 0)
1100
	      {
1101
		 if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1102
		    ldat = ab_dat[a_ind-1];
1103
		 else
1104
		    ldat = rat_dat[r_ind-1];
1105
#ifdef _ZINSAENDERUNG
1106
		 if (LastAend && LastAend > ldat)
1107
		    ldat = LastAend;
1108
#endif
1109
		 tg = tageber (rat_dat[r_ind]) - tageber (ldat);
1110
	      }
1111
	      else
1112
	         tg = tageber (rat_dat[r_ind]) - tageber (TpPars->ragab);
1113
 
1114
	      zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1115
#ifdef _ZINSAENDERUNG
1116
	      if (LastAend)
1117
	      {
1118
		 LastAend = 0L;
1119
		 zi1 += aZins;
1120
	      }
1121
#endif
1122
              zi1 = runden (zi1, rund_fakt);
1123
	      zins += zi1;
1124
	      kzi += zi1;
1125
 
1126
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1127
	      {
1128
	         if (!stop && r_ind > 0 && DTable.rkapi < rat)
1129
	         {
1130
	            max_rat = r_ind + 1;
1131
	            max_abs = a_ind + 1;
1132
	            real_rat = max_rat - Abzug;
1133
	            ab_dat[a_ind] = rat_dat[r_ind];
1134
	            index = max_rat + max_abs;
1135
	            stop = TRUE;
1136
	         }
1137
	      }
1138
 
1139
	      if (r_ind == (max_rat - 1)) 		/* letzte Rate */
1140
	      {
1141
		 if (reh != 1)
1142
		 {
1143
		    zi2 = (kap < rat) ? rat - kap : kap - rat;
1144
		    zi2 = rat - zi2 + zins;
1145
//	            zi2 = rat + ((TpPars->gesamt + zins) - (rat * (LFLOAT)real_rat));
1146
		 }
1147
	         else
1148
	            zi2 = rat - ((rat * (double)real_rat) - TpPars->rahmen);
1149
 
1150
	         rat = zi2 + TpPars->spesen;
1151
	      }
1152
 
1153
	      TpPars->lrate = rat;
1154
	      tilg += rat;				/* Tilgung */
1155
 
1156
	      if (DTable.datum >= TpPars->dvon)		/* Restkapital */
1157
	         kap -= rat;
1158
 
1159
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1160
	      DTable.tilg = 0.0;
1161
	      DTable.rate = rat;
1162
	      DTable.zinsen = zi1;
1163
	      r_ind++;
1164
	   }
1165
	   else
1166
	   {
1167
	      DTable.datum = ab_dat[a_ind];
1168
	      DTable.kz = 'A';
1169
 
1170
	      if (r_ind > 0 && rat_dat[r_ind-1] <= ab_dat[0])
1171
	         DTable.kapital = TpPars->rahmen;
1172
	      else
1173
	         DTable.kapital = (kap >= 0.0) ? kap : 0.0;
1174
 
1175
	      kap += TpPars->spesen;
1176
	      DTable.rate = 0.0;
1177
 
1178
	      if (r_ind > 0)
1179
              {
1180
	         if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1181
	            ldat = ab_dat[a_ind-1];
1182
	         else
1183
	            ldat = rat_dat[r_ind-1];
1184
#ifdef _ZINSAENDERUNG
1185
		 if (LastAend && LastAend > ldat)
1186
		    LastAend = 0L;
1187
#endif
1188
		 tg = tageber (ab_dat[a_ind]) - tageber (ldat);
1189
 
1190
	         if (tg > 0)
1191
                 {
1192
		    zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1193
#ifdef _ZINSAENDERUNG
1194
	            if (LastAend)
1195
	            { 
1196
		       LastAend = 0L;
1197
		       zi1 += aZins;
1198
	            }
1199
#endif
1200
		    zins += zi1;
1201
	            kzi += runden (zi1, rund_fakt);
1202
	            zins = runden (zins, rund_fakt);
1203
		 }
1204
#ifdef _ZINSAENDERUNG
1205
		 else if (LastAend)
1206
		    LastAend = 0L;
1207
#endif
1208
	      }
1209
 
1210
	      DTable.zinsen = zins;
1211
	      TpPars->gesamt += zins + TpPars->spesen;	/* Gesamtbelastung */
1212
 
1213
	      if (reh != 2)
1214
	         tilg -= zins;      		/* Tilgung - Zinsen */
1215
 
1216
	      if (DTable.datum < TpPars->dvon)
1217
	         DTable.tilg = 0.0;
1218
	      else
1219
	         DTable.tilg = tilg;
1220
 
1221
	      if (reh != 1)
1222
	         kap += zins;
1223
 
1224
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1225
	      zins = 0.0;
1226
	      tilg = 0.0;
1227
	      a_ind++;
1228
	   } /* end if */
1229
 
1230
	   if (DTable.datum < TpPars->dvon && DTable.kz == 'R')
1231
	   {
1232
              if (TpPars->fixrate)
1233
	         Abzug++;
1234
	      else
1235
	         real_rat--;
1236
 
1237
	      continue;
1238
	   }
1239
 
60 andreas 1240
	   if (!TpPars->effekt)
1241
	   {
1242
	      write (fd, &DTable, sizeof (DTABLE));
1243
	      offset += (long)sizeof (DTABLE);
1244
	   }
71 andreas 1245
	   else if (DTable.datum >= effend)
60 andreas 1246
	      break;
53 andreas 1247
	} /* end for */
1248
 
1249
	if (TpPars->fixrate == TRUE)
1250
	   TpPars->dbis = rat_dat[r_ind-1];
1251
 
1252
	TpPars->anzraten = real_rat;
1253
	DTable.datum = (long)real_rat;		/* Laufzeit */
1254
	DTable.kz = 'E';			/* Ergebnis */
1255
	DTable.kapital = TpPars->rahmen;
1256
	DTable.tilg = TpPars->gesamt;
1257
	DTable.rate = 0.0;
1258
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1259
 
1260
	if (TpPars->zuschprz > 0.0)
1261
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1262
	else
1263
	   TpPars->zuschuss = 0.0;
1264
 
1265
	DTable.zinsen = TpPars->gesamt - TpPars->rahmen;
1266
	TpPars->gesamt -= TpPars->zuschuss;
1267
 
1268
	// Annuitätenzuschuß berechnen und anzeigen
1269
 
1270
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1271
	{
1272
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1273
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1274
	   TpPars->antotal -= TpPars->zuschuss;
1275
	}
1276
	else
1277
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1278
 
1279
	DTable.rkapi = TpPars->lrate;
60 andreas 1280
 
1281
	if (!TpPars->effekt)
1282
	   write (fd, &DTable, sizeof (DTABLE));
53 andreas 1283
#ifdef _ZINSAENDERUNG
64 andreas 1284
//	if (TpPars->gewicht > 0.0)
1285
//	   TpPars->zssoll = TpPars->gewicht;
53 andreas 1286
 
1287
	zaf.close();
1288
#endif
64 andreas 1289
	tmpFile.flush();
1290
 
60 andreas 1291
	if (!TpPars->effekt)
1292
	{
1293
	   lseek (fd, 0L, 0);
1294
	   write (fd, TpPars, sizeof (TPPARS));
1295
	}
64 andreas 1296
	else
1297
	{
1298
	   // Zinsen nach einem Jahr ermitteln
1299
	   tmpFile.flush();
1300
	   lseek (fd, (long)sizeof(TPPARS), 0);
1301
	   zins = 0.0;
60 andreas 1302
 
64 andreas 1303
	   while (read (fd, &DTable, sizeof(DTABLE)) >= sizeof(DTABLE))
1304
	   {
1305
	      if (DTable.kz == 'R' && DTable.datum >= effend)
1306
		 break;
1307
 
1308
	      if (DTable.kz == 'R')
1309
		 zins += DTable.zinsen;
1310
	   }
1311
 
71 andreas 1312
	   if ((TpPars->ezins - 0.1) < zins && (TpPars->ezins + 0.1) > zins)
1313
	   {
1314
	      tmpFile.close();
1315
	      TpPars->gewicht = zins;
1316
	      return 0;
1317
	   }
1318
	   else
1319
	   {
1320
	      tmpFile.close();
1321
	      TpPars->gewicht = zins;
1322
 
1323
	      if (TpPars->ezins < zins)
1324
		 TpPars->effformel += 0.0001;
1325
	      else
1326
		 TpPars->effformel -= 0.0001;
1327
 
1328
	      return -2;		// Für nächste Iteration präparieren.
1329
	   }
64 andreas 1330
	}
1331
 
53 andreas 1332
	tmpFile.close ();
1333
	return 0;
1334
}
1335
 
1336
#ifdef _ZINSAENDERUNG
1337
void TRech::DekZiAend (int fdZins, long *zoff, long size, ZIAEND *Zi)
1338
{
1339
int old_rind, old_aind;
1340
long datum;
1341
double old_kap;
1342
 
1343
	TpPars->gewicht = TpPars->zssoll;
1344
	TpPars->zssoll = Zi->Zins;
1345
 
1346
	if (Zi->Rate)
1347
        {
1348
	   old_kap = kap;
1349
	   old_rind = r_ind;
1350
	   old_aind = a_ind;
1351
 
1352
	   if (rat_dat[r_ind] > ab_dat[a_ind])
1353
	      datum = ab_dat[a_ind];
1354
	   else
1355
	      datum = rat_dat[r_ind];
1356
 
1357
	   GetRate (kap, Zi->Datum, datum);
1358
	   kap = old_kap;
1359
	   r_ind = old_rind;
1360
	   a_ind = old_aind;
1361
	   TpPars->ergrate = rat;
1362
	}
1363
	else if (Zi->FixRate)
1364
        {
1365
	   rat = Zi->NewRate;
1366
	   TpPars->ergrate = rat;
1367
	}
1368
 
1369
	if (*zoff < size)
1370
	   read (fdZins, Zi, sizeof(ZIAEND));
1371
	else
1372
	   close (fdZins);
1373
 
1374
        *zoff += (long)sizeof(ZIAEND);
1375
}
1376
 
1377
#endif
1378
int TRech::AntizipativPlan ()
1379
{
1380
QString hdir = QDir::homeDirPath ();
1381
QFile tmpFile;
1382
int fd, index, i;
1383
int real_rat, Abzug;
1384
long t1, t2, r_dat, old_par, r_tg, a_tg;
1385
double zins, tilg, kzi, sumrat;
1386
long offset, loff;
1387
BOOL stop;
1388
DTABLE old_tab;
1389
 
1390
	/* Planerstellung */
1391
	hdir.append("/.date_tbl.dat");
1392
	tmpFile.setName(hdir);
1393
 
1394
	if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
1395
	{
1396
	   KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
1397
	   return 1;
1398
	}
1399
 
1400
 
1401
	fd = tmpFile.handle();
1402
	offset = 0L;
1403
	index = max_abs - 1 + max_rat;
1404
 
1405
	/* Ausgangsdaten schreiben */
1406
	write (fd, TpPars, sizeof (TPPARS));
1407
	offset += (long)sizeof (TPPARS);
1408
 
1409
	/* Initialisierung der Schleife */
1410
 
1411
	a_ind = r_ind = 0;
1412
	kap = TpPars->rahmen;
1413
	zins = 0.0;
1414
	TpPars->gesamt = kap;
1415
	tilg = kzi = 0.0;
1416
	TpPars->abschl = ab_dat[0];
1417
	stop = FALSE;			// TRUE wenn Laufzeitende bei Ratenvorgabe
1418
	real_rat = max_rat;
1419
        Abzug = 0;			// wird nur bei Ratenvorgabe verwendet
1420
 
1421
	/* Schleife zur Berechnung der Gesamtbelastung (Antizipativ) */
1422
 
1423
	a_ind++;			/* Start bei 1! */
1424
	ab_tag = tageber (ab_dat[a_ind]);
1425
	tageber (TpPars->ragab);
1426
	tg_alt = tg_par;
1427
	sumrat = 0.0;
1428
	DTable.rkapi = runden (kap, rund_fakt);
1429
	DTable.kapital = runden (kap, rund_fakt);
1430
	loff = offset;
1431
	old_tab.datum = ab_dat[0];
1432
	old_tab.kz = 'A';
1433
	old_tab.kapital = TpPars->rahmen;
1434
	write (fd, &old_tab, sizeof (DTABLE));	/* Platzhalter */
1435
	offset += (long)sizeof (DTABLE);
1436
	r_dat = 0L;
1437
 
1438
	for (i = 0; i < index-1; i++)
1439
	{
1440
	   if ((rat_dat[r_ind] < ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1441
	   {
1442
	      DTable.datum = rat_dat[r_ind];
1443
	      DTable.kz = 'R';
1444
 
1445
	      tageber (rat_dat[r_ind+1]);
1446
	      t1 = ab_tag - tg_alt;
1447
	      t2 = ab_tag - tg_par;
1448
 
1449
	      if (t2 < 0L)
1450
		 t2 = 0L;
1451
 
1452
              // Berechnung der letzten Rate
1453
	      if (rat > (DTable.rkapi - TpPars->kapital))
1454
	         rat = runden (DTable.rkapi - TpPars->kapital, rund_fakt);
1455
 
1456
	      sumrat += rat;
1457
 
1458
//              if (reh == 1)		// Kapitalraten
1459
	         kap -= rat;
1460
 
1461
	      if (reh != 1)		// Pauschalraten
1462
	      {
1463
	         kzi = kap * TpPars->zssoll * ((double)t1 *
1464
	               (divisor - (double)t2 * TpPars->zssoll) -
1465
		       (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1466
		       ((divisor - (double)t1 * TpPars->zssoll) *
1467
		       (divisor - (double)t2 * TpPars->zssoll));
1468
	      }
1469
	      else			// Kapitalraten
1470
//	         kzi = kap * (tg_par - tg_alt) * TpPars->zssoll / divisor;
1471
		 kzi = kap * (t1 - t2) * TpPars->zssoll / divisor;
1472
 
1473
	      kzi = runden (kzi, rund_fakt);
1474
	      tg_alt = tg_par;
1475
	      zins += kzi;
1476
 
1477
              if (reh == 1)		// Kapitalraten
1478
		 DTable.rkapi = DTable.kapital - sumrat;
1479
	      else			// Pauschalraten
1480
		 DTable.rkapi = DTable.kapital + zins - sumrat;
1481
 
1482
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1483
	      {
1484
		 if (!stop && r_ind > 0 && DTable.rkapi < rat)
1485
	         {
1486
	            max_rat = r_ind + 1;
1487
	            max_abs = a_ind + 1;
1488
	            ab_dat[a_ind] = rat_dat[r_ind];
1489
                    real_rat = max_rat - Abzug;
1490
	            index = max_rat + max_abs;
1491
	            stop = TRUE;
1492
	         }
1493
	      }
1494
 
1495
              if (reh == 1)		// Kapitalraten
1496
		 DTable.tilg = rat;
1497
	      else                 	// Pauschalraten
1498
		 DTable.tilg = rat - kzi;
1499
 
1500
	      tilg += DTable.tilg;
1501
	      TpPars->lrate = rat;
1502
 
1503
	      DTable.rate = rat;
1504
	      DTable.zinsen = kzi;
1505
	      r_ind++;
1506
	   }
1507
	   else			/* Abschluß */
1508
	   {
1509
	      DTable.datum = ab_dat[a_ind];
1510
 
1511
	      if (i == (index-2))
1512
	      {
1513
		 DTable.kz = 'R';
1514
		 max_rat++;
1515
//		 TpPars->lrate = DTable.kapital - tilg;
1516
	      }
1517
	      else
1518
	         DTable.kz = 'A';
1519
 
1520
	      if (a_ind > 1)
1521
              {
1522
                 old_par = tg_par; 
1523
 
1524
		 if (reh == 1)			// Kapitalraten
1525
                 {
1526
		    r_tg = tageber (r_dat);
1527
                    a_tg = tageber (ab_dat[a_ind-1]);
1528
		    t1 = r_tg - a_tg;
1529
		    t2 = 0L;
1530
		 }
1531
		 else
1532
		 {
1533
		    a_tg = tageber (ab_dat[a_ind]);
1534
		    tageber (ab_dat[a_ind-1]);
1535
		    t1 = a_tg - tg_par;
1536
		    tageber (r_dat);
1537
		    t2 = ab_tag - tg_par;
1538
		 }
1539
 
1540
		 tg_par = old_par;
1541
 
1542
		 if (reh != 1)			// Pauschalraten
1543
                 {
1544
		    kzi = DTable.kapital * TpPars->zssoll * ((double)t1 *
1545
	                  (divisor - (double)t2 * TpPars->zssoll) -
1546
		          (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1547
		          ((divisor - (double)t1 * TpPars->zssoll) *
1548
			  (divisor - (double)t2 * TpPars->zssoll));
1549
                 }
1550
		 else                           // Kapitalraten
1551
		    kzi = DTable.kapital * t1 * TpPars->zssoll / divisor;
1552
 
1553
		 kzi = runden (kzi, rund_fakt);
1554
		 zins += kzi;
1555
 
1556
		 if (reh != 1)
1557
		 {
1558
                    tilg -= kzi;
1559
		    DTable.rkapi = DTable.kapital - tilg;
1560
                 }
1561
	      }
1562
 
1563
	      DTable.kapital -= tilg;
1564
	      r_dat = rat_dat[r_ind];
1565
 
1566
	      if (i == (index - 2))
1567
	      {
1568
	         DTable.rate = DTable.kapital;
1569
		 TpPars->lrate = DTable.rate;
1570
	         DTable.zinsen = 0.0;
1571
	         DTable.tilg = DTable.kapital;
1572
	         DTable.rkapi = 0.0;
1573
	      }
1574
	      else
1575
	      {
1576
	         DTable.rate = runden (sumrat, rund_fakt);
1577
	         DTable.zinsen = zins;
1578
	         DTable.tilg = tilg;
1579
	      }
1580
 
1581
	      TpPars->gesamt += zins;		/* Gesamtbelastung */
1582
 
1583
	      tmpFile.flush();
1584
	      lseek (fd, loff, 0);
1585
	      /* Füllen der Struktur */
1586
	      old_tab.tilg = tilg;
1587
	      old_tab.rate = 0.0;
1588
	      old_tab.zinsen = zins;
1589
 
1590
              if (reh == 1)
1591
		 old_tab.rkapi = old_tab.kapital;
1592
              else
1593
		 old_tab.rkapi = old_tab.kapital + zins;
1594
 
1595
	      write (fd, &old_tab, sizeof (DTABLE));
1596
	      old_tab.kapital = DTable.kapital;
1597
	      old_tab.datum = DTable.datum;
1598
	      lseek (fd, offset, 0);
1599
	      loff = offset;
1600
 
1601
//              if (reh == 1)			// Kapitalraten
1602
		 kap = DTable.kapital;
1603
 
1604
	      zins = 0.0;
1605
	      tilg = 0.0;
1606
	      sumrat = 0.0;
1607
	      a_ind++;
1608
	      ab_tag = tageber (ab_dat[a_ind]);
1609
	   } /* end if */
1610
 
1611
	   if (DTable.datum <= ab_dat[0] && DTable.datum < TpPars->dvon &&
1612
	       DTable.kz == 'R')
1613
	   {
1614
	      if (TpPars->fixrate)
1615
		 Abzug++;
1616
	      else
1617
	         real_rat--;
1618
 
1619
	      continue;
1620
           }
1621
 
1622
	   write (fd, &DTable, sizeof (DTABLE));
1623
	   offset += (long)sizeof (DTABLE);
1624
	} /* end for */
1625
 
1626
	if (TpPars->fixrate == TRUE)
1627
	   TpPars->dbis = rat_dat[r_ind-1];
1628
 
1629
	TpPars->anzraten = real_rat;
1630
	DTable.datum = (long)real_rat;		/* Laufzeit */
1631
	DTable.kz = 'E';			/* Ergebnis */
1632
	DTable.kapital = TpPars->rahmen;
1633
	DTable.tilg = TpPars->gesamt;
1634
	DTable.rate = 0.0;
1635
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1636
 
1637
	if (TpPars->zuschprz > 0.0)
1638
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1639
	else
1640
	   TpPars->zuschuss = 0.0;
1641
 
1642
	DTable.zinsen = kzi;
1643
	TpPars->gesamt -= TpPars->zuschuss;
1644
 
1645
	// Annuitätenzuschuß berechnen und anzeigen
1646
 
1647
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1648
	{
1649
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1650
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1651
	   TpPars->antotal -= TpPars->zuschuss;
1652
	}
1653
	else
1654
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1655
 
1656
	DTable.rkapi = TpPars->lrate;
1657
	write (fd, &DTable, sizeof (DTABLE));
1658
	tmpFile.flush();
1659
	lseek (fd, 0L, 0);
1660
	write (fd, TpPars, sizeof (TPPARS));
1661
	tmpFile.close ();
1662
	return 0;
1663
}
1664
 
1665
void TRech::init_global_vars ()
1666
{
1667
int i;
1668
 
1669
	ab_tag = 0L;
1670
	zi_rat = 0.0;
1671
	zi_kap = 0.0;
1672
	dat_par = 0L;
70 andreas 1673
	reh = 0;
1674
	divisor = 0.0;
1675
	a_ind = 0;
1676
	r_ind = 0;
1677
	max_abs = max_rat = 0;
1678
	pos = 0L;
1679
	a_dat = 0L;
1680
	tg_par = tg_alt = 0L;
1681
	r_dat = 0L;
1682
	ldat = 0L;
1683
	rat = kap = 0.0;
53 andreas 1684
 
1685
	for (i = 0; i < 1200; i++)
1686
	{
1687
	   rat_dat[i] = 0L;
1688
	   ab_dat[i] = 0L;
1689
	   rat_anz[i] = 0L;
1690
	}
1691
}