Subversion Repositories public

Rev

Rev 60 | Rev 70 | 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);
842
	kap = rahmen;
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
 
53 andreas 1017
	/* Schleife zur Berechnung der Gesamtbelastung (Dekursiv) */
1018
 
1019
	for (i = 0; i < index; i++)
1020
	{
1021
#ifdef _ZINSAENDERUNG
1022
	   // Ist eine Zinssatzänderung gewünscht?
1023
 
1024
	   if ((Zi.Datum < rat_dat[r_ind-1] || Zi.Datum < ab_dat[a_ind]) &&
1025
	       zoff <= sbuf.st_size && TpPars->ziaend)
1026
	   {
1027
	      DTable.datum = Zi.Datum;
1028
	      DTable.kz = 'Z';
1029
	      DTable.kapital = kap;
1030
	      index++;
1031
 
1032
	      if (a_ind > 0)
1033
	      {
1034
		 if (ab_dat[a_ind-1] < Zi.Datum)
1035
		    ldat = ab_dat[a_ind-1];
1036
		 else
1037
		    ldat = Zi.Datum;
1038
 
1039
		 tg = tageber (Zi.Datum) - tageber (ldat);
1040
	      }
1041
	      else
1042
	         tg = tageber (Zi.Datum) - tageber (TpPars->ragab);
1043
 
1044
	      aZins = kap * (double)tg * TpPars->zssoll / divisor;
1045
	      kap += runden (aZins, rund_fakt);
1046
              LastAend = Zi.Datum;
64 andreas 1047
	      DTable.rate = Zi.Zins;
53 andreas 1048
	      DekZiAend (fdZins, &zoff, sbuf.st_size, &Zi);
1049
	      kap = DTable.kapital;
1050
	   }
1051
	   else if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1052
#else
1053
	   if ((rat_dat[r_ind] <= ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1054
#endif
1055
	   {
1056
	      DTable.datum = rat_dat[r_ind];
1057
	      DTable.kz = 'R';
1058
	      DTable.kapital = runden (kap, rund_fakt);
1059
 
1060
	      if (r_ind > 0)
1061
	      {
1062
		 if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1063
		    ldat = ab_dat[a_ind-1];
1064
		 else
1065
		    ldat = rat_dat[r_ind-1];
1066
#ifdef _ZINSAENDERUNG
1067
		 if (LastAend && LastAend > ldat)
1068
		    ldat = LastAend;
1069
#endif
1070
		 tg = tageber (rat_dat[r_ind]) - tageber (ldat);
1071
	      }
1072
	      else
1073
	         tg = tageber (rat_dat[r_ind]) - tageber (TpPars->ragab);
1074
 
1075
	      zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1076
#ifdef _ZINSAENDERUNG
1077
	      if (LastAend)
1078
	      {
1079
		 LastAend = 0L;
1080
		 zi1 += aZins;
1081
	      }
1082
#endif
1083
              zi1 = runden (zi1, rund_fakt);
1084
	      zins += zi1;
1085
	      kzi += zi1;
1086
 
1087
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1088
	      {
1089
	         if (!stop && r_ind > 0 && DTable.rkapi < rat)
1090
	         {
1091
	            max_rat = r_ind + 1;
1092
	            max_abs = a_ind + 1;
1093
	            real_rat = max_rat - Abzug;
1094
	            ab_dat[a_ind] = rat_dat[r_ind];
1095
	            index = max_rat + max_abs;
1096
	            stop = TRUE;
1097
	         }
1098
	      }
1099
 
1100
	      if (r_ind == (max_rat - 1)) 		/* letzte Rate */
1101
	      {
1102
		 if (reh != 1)
1103
		 {
1104
		    zi2 = (kap < rat) ? rat - kap : kap - rat;
1105
		    zi2 = rat - zi2 + zins;
1106
//	            zi2 = rat + ((TpPars->gesamt + zins) - (rat * (LFLOAT)real_rat));
1107
		 }
1108
	         else
1109
	            zi2 = rat - ((rat * (double)real_rat) - TpPars->rahmen);
1110
 
1111
	         rat = zi2 + TpPars->spesen;
1112
	      }
1113
 
1114
	      TpPars->lrate = rat;
1115
	      tilg += rat;				/* Tilgung */
1116
 
1117
	      if (DTable.datum >= TpPars->dvon)		/* Restkapital */
1118
	         kap -= rat;
1119
 
1120
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1121
	      DTable.tilg = 0.0;
1122
	      DTable.rate = rat;
1123
	      DTable.zinsen = zi1;
1124
	      r_ind++;
1125
	   }
1126
	   else
1127
	   {
1128
	      DTable.datum = ab_dat[a_ind];
1129
	      DTable.kz = 'A';
1130
 
1131
	      if (r_ind > 0 && rat_dat[r_ind-1] <= ab_dat[0])
1132
	         DTable.kapital = TpPars->rahmen;
1133
	      else
1134
	         DTable.kapital = (kap >= 0.0) ? kap : 0.0;
1135
 
1136
	      kap += TpPars->spesen;
1137
	      DTable.rate = 0.0;
1138
 
1139
	      if (r_ind > 0)
1140
              {
1141
	         if (ab_dat[a_ind-1] > rat_dat[r_ind-1])
1142
	            ldat = ab_dat[a_ind-1];
1143
	         else
1144
	            ldat = rat_dat[r_ind-1];
1145
#ifdef _ZINSAENDERUNG
1146
		 if (LastAend && LastAend > ldat)
1147
		    LastAend = 0L;
1148
#endif
1149
		 tg = tageber (ab_dat[a_ind]) - tageber (ldat);
1150
 
1151
	         if (tg > 0)
1152
                 {
1153
		    zi1 = kap * (double)tg * TpPars->zssoll / divisor;
1154
#ifdef _ZINSAENDERUNG
1155
	            if (LastAend)
1156
	            { 
1157
		       LastAend = 0L;
1158
		       zi1 += aZins;
1159
	            }
1160
#endif
1161
		    zins += zi1;
1162
	            kzi += runden (zi1, rund_fakt);
1163
	            zins = runden (zins, rund_fakt);
1164
		 }
1165
#ifdef _ZINSAENDERUNG
1166
		 else if (LastAend)
1167
		    LastAend = 0L;
1168
#endif
1169
	      }
1170
 
1171
	      DTable.zinsen = zins;
1172
	      TpPars->gesamt += zins + TpPars->spesen;	/* Gesamtbelastung */
1173
 
1174
	      if (reh != 2)
1175
	         tilg -= zins;      		/* Tilgung - Zinsen */
1176
 
1177
	      if (DTable.datum < TpPars->dvon)
1178
	         DTable.tilg = 0.0;
1179
	      else
1180
	         DTable.tilg = tilg;
1181
 
1182
	      if (reh != 1)
1183
	         kap += zins;
1184
 
1185
	      DTable.rkapi = (kap >= 0.0) ? kap : 0.0;
1186
	      zins = 0.0;
1187
	      tilg = 0.0;
1188
	      a_ind++;
1189
	   } /* end if */
1190
 
1191
	   if (DTable.datum < TpPars->dvon && DTable.kz == 'R')
1192
	   {
1193
              if (TpPars->fixrate)
1194
	         Abzug++;
1195
	      else
1196
	         real_rat--;
1197
 
1198
	      continue;
1199
	   }
1200
 
60 andreas 1201
	   if (!TpPars->effekt)
1202
	   {
1203
	      write (fd, &DTable, sizeof (DTABLE));
1204
	      offset += (long)sizeof (DTABLE);
1205
	   }
1206
	   else if (DTable.datum > effend)
1207
	      break;
53 andreas 1208
	} /* end for */
1209
 
1210
	if (TpPars->fixrate == TRUE)
1211
	   TpPars->dbis = rat_dat[r_ind-1];
1212
 
1213
	TpPars->anzraten = real_rat;
1214
	DTable.datum = (long)real_rat;		/* Laufzeit */
1215
	DTable.kz = 'E';			/* Ergebnis */
1216
	DTable.kapital = TpPars->rahmen;
1217
	DTable.tilg = TpPars->gesamt;
1218
	DTable.rate = 0.0;
1219
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1220
 
1221
	if (TpPars->zuschprz > 0.0)
1222
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1223
	else
1224
	   TpPars->zuschuss = 0.0;
1225
 
1226
	DTable.zinsen = TpPars->gesamt - TpPars->rahmen;
1227
	TpPars->gesamt -= TpPars->zuschuss;
1228
 
1229
	// Annuitätenzuschuß berechnen und anzeigen
1230
 
1231
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1232
	{
1233
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1234
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1235
	   TpPars->antotal -= TpPars->zuschuss;
1236
	}
1237
	else
1238
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1239
 
1240
	DTable.rkapi = TpPars->lrate;
60 andreas 1241
 
1242
	if (!TpPars->effekt)
1243
	   write (fd, &DTable, sizeof (DTABLE));
53 andreas 1244
#ifdef _ZINSAENDERUNG
64 andreas 1245
//	if (TpPars->gewicht > 0.0)
1246
//	   TpPars->zssoll = TpPars->gewicht;
53 andreas 1247
 
1248
	zaf.close();
1249
#endif
64 andreas 1250
	tmpFile.flush();
1251
 
60 andreas 1252
	if (!TpPars->effekt)
1253
	{
1254
	   lseek (fd, 0L, 0);
1255
	   write (fd, TpPars, sizeof (TPPARS));
1256
	}
64 andreas 1257
	else
1258
	{
1259
	   // Zinsen nach einem Jahr ermitteln
1260
	   tmpFile.flush();
1261
	   lseek (fd, (long)sizeof(TPPARS), 0);
1262
	   zins = 0.0;
60 andreas 1263
 
64 andreas 1264
	   while (read (fd, &DTable, sizeof(DTABLE)) >= sizeof(DTABLE))
1265
	   {
1266
	      if (DTable.kz == 'R' && DTable.datum >= effend)
1267
		 break;
1268
 
1269
	      if (DTable.kz == 'R')
1270
		 zins += DTable.zinsen;
1271
	   }
1272
 
1273
	   TpPars->effformel = 100.0 - (100.0 / TpPars->ezins * zins);
1274
	}
1275
 
53 andreas 1276
	tmpFile.close ();
1277
	return 0;
1278
}
1279
 
1280
#ifdef _ZINSAENDERUNG
1281
void TRech::DekZiAend (int fdZins, long *zoff, long size, ZIAEND *Zi)
1282
{
1283
int old_rind, old_aind;
1284
long datum;
1285
double old_kap;
1286
 
1287
	TpPars->gewicht = TpPars->zssoll;
1288
	TpPars->zssoll = Zi->Zins;
1289
 
1290
	if (Zi->Rate)
1291
        {
1292
	   old_kap = kap;
1293
	   old_rind = r_ind;
1294
	   old_aind = a_ind;
1295
 
1296
	   if (rat_dat[r_ind] > ab_dat[a_ind])
1297
	      datum = ab_dat[a_ind];
1298
	   else
1299
	      datum = rat_dat[r_ind];
1300
 
1301
	   GetRate (kap, Zi->Datum, datum);
1302
	   kap = old_kap;
1303
	   r_ind = old_rind;
1304
	   a_ind = old_aind;
1305
	   TpPars->ergrate = rat;
1306
	}
1307
	else if (Zi->FixRate)
1308
        {
1309
	   rat = Zi->NewRate;
1310
	   TpPars->ergrate = rat;
1311
	}
1312
 
1313
	if (*zoff < size)
1314
	   read (fdZins, Zi, sizeof(ZIAEND));
1315
	else
1316
	   close (fdZins);
1317
 
1318
        *zoff += (long)sizeof(ZIAEND);
1319
}
1320
 
1321
#endif
1322
int TRech::AntizipativPlan ()
1323
{
1324
QString hdir = QDir::homeDirPath ();
1325
QFile tmpFile;
1326
int fd, index, i;
1327
int real_rat, Abzug;
1328
long t1, t2, r_dat, old_par, r_tg, a_tg;
1329
double zins, tilg, kzi, sumrat;
1330
long offset, loff;
1331
BOOL stop;
1332
DTABLE old_tab;
1333
 
1334
	/* Planerstellung */
1335
	hdir.append("/.date_tbl.dat");
1336
	tmpFile.setName(hdir);
1337
 
1338
	if (tmpFile.open(IO_ReadWrite | IO_Truncate) == FALSE)
1339
	{
1340
	   KMessageBox::error(0, QString("Could not open file for reading: %1").arg(tmpFile.errorString()));
1341
	   return 1;
1342
	}
1343
 
1344
 
1345
	fd = tmpFile.handle();
1346
	offset = 0L;
1347
	index = max_abs - 1 + max_rat;
1348
 
1349
	/* Ausgangsdaten schreiben */
1350
	write (fd, TpPars, sizeof (TPPARS));
1351
	offset += (long)sizeof (TPPARS);
1352
 
1353
	/* Initialisierung der Schleife */
1354
 
1355
	a_ind = r_ind = 0;
1356
	kap = TpPars->rahmen;
1357
	zins = 0.0;
1358
	TpPars->gesamt = kap;
1359
	tilg = kzi = 0.0;
1360
	TpPars->abschl = ab_dat[0];
1361
	stop = FALSE;			// TRUE wenn Laufzeitende bei Ratenvorgabe
1362
	real_rat = max_rat;
1363
        Abzug = 0;			// wird nur bei Ratenvorgabe verwendet
1364
 
1365
	/* Schleife zur Berechnung der Gesamtbelastung (Antizipativ) */
1366
 
1367
	a_ind++;			/* Start bei 1! */
1368
	ab_tag = tageber (ab_dat[a_ind]);
1369
	tageber (TpPars->ragab);
1370
	tg_alt = tg_par;
1371
	sumrat = 0.0;
1372
	DTable.rkapi = runden (kap, rund_fakt);
1373
	DTable.kapital = runden (kap, rund_fakt);
1374
	loff = offset;
1375
	old_tab.datum = ab_dat[0];
1376
	old_tab.kz = 'A';
1377
	old_tab.kapital = TpPars->rahmen;
1378
	write (fd, &old_tab, sizeof (DTABLE));	/* Platzhalter */
1379
	offset += (long)sizeof (DTABLE);
1380
	r_dat = 0L;
1381
 
1382
	for (i = 0; i < index-1; i++)
1383
	{
1384
	   if ((rat_dat[r_ind] < ab_dat[a_ind] && r_ind < max_rat) || a_ind >= max_abs)
1385
	   {
1386
	      DTable.datum = rat_dat[r_ind];
1387
	      DTable.kz = 'R';
1388
 
1389
	      tageber (rat_dat[r_ind+1]);
1390
	      t1 = ab_tag - tg_alt;
1391
	      t2 = ab_tag - tg_par;
1392
 
1393
	      if (t2 < 0L)
1394
		 t2 = 0L;
1395
 
1396
              // Berechnung der letzten Rate
1397
	      if (rat > (DTable.rkapi - TpPars->kapital))
1398
	         rat = runden (DTable.rkapi - TpPars->kapital, rund_fakt);
1399
 
1400
	      sumrat += rat;
1401
 
1402
//              if (reh == 1)		// Kapitalraten
1403
	         kap -= rat;
1404
 
1405
	      if (reh != 1)		// Pauschalraten
1406
	      {
1407
	         kzi = kap * TpPars->zssoll * ((double)t1 *
1408
	               (divisor - (double)t2 * TpPars->zssoll) -
1409
		       (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1410
		       ((divisor - (double)t1 * TpPars->zssoll) *
1411
		       (divisor - (double)t2 * TpPars->zssoll));
1412
	      }
1413
	      else			// Kapitalraten
1414
//	         kzi = kap * (tg_par - tg_alt) * TpPars->zssoll / divisor;
1415
		 kzi = kap * (t1 - t2) * TpPars->zssoll / divisor;
1416
 
1417
	      kzi = runden (kzi, rund_fakt);
1418
	      tg_alt = tg_par;
1419
	      zins += kzi;
1420
 
1421
              if (reh == 1)		// Kapitalraten
1422
		 DTable.rkapi = DTable.kapital - sumrat;
1423
	      else			// Pauschalraten
1424
		 DTable.rkapi = DTable.kapital + zins - sumrat;
1425
 
1426
	      if (TpPars->fixrate == TRUE)	/* Ratenvorgabe */
1427
	      {
1428
		 if (!stop && r_ind > 0 && DTable.rkapi < rat)
1429
	         {
1430
	            max_rat = r_ind + 1;
1431
	            max_abs = a_ind + 1;
1432
	            ab_dat[a_ind] = rat_dat[r_ind];
1433
                    real_rat = max_rat - Abzug;
1434
	            index = max_rat + max_abs;
1435
	            stop = TRUE;
1436
	         }
1437
	      }
1438
 
1439
              if (reh == 1)		// Kapitalraten
1440
		 DTable.tilg = rat;
1441
	      else                 	// Pauschalraten
1442
		 DTable.tilg = rat - kzi;
1443
 
1444
	      tilg += DTable.tilg;
1445
	      TpPars->lrate = rat;
1446
 
1447
	      DTable.rate = rat;
1448
	      DTable.zinsen = kzi;
1449
	      r_ind++;
1450
	   }
1451
	   else			/* Abschluß */
1452
	   {
1453
	      DTable.datum = ab_dat[a_ind];
1454
 
1455
	      if (i == (index-2))
1456
	      {
1457
		 DTable.kz = 'R';
1458
		 max_rat++;
1459
//		 TpPars->lrate = DTable.kapital - tilg;
1460
	      }
1461
	      else
1462
	         DTable.kz = 'A';
1463
 
1464
	      if (a_ind > 1)
1465
              {
1466
                 old_par = tg_par; 
1467
 
1468
		 if (reh == 1)			// Kapitalraten
1469
                 {
1470
		    r_tg = tageber (r_dat);
1471
                    a_tg = tageber (ab_dat[a_ind-1]);
1472
		    t1 = r_tg - a_tg;
1473
		    t2 = 0L;
1474
		 }
1475
		 else
1476
		 {
1477
		    a_tg = tageber (ab_dat[a_ind]);
1478
		    tageber (ab_dat[a_ind-1]);
1479
		    t1 = a_tg - tg_par;
1480
		    tageber (r_dat);
1481
		    t2 = ab_tag - tg_par;
1482
		 }
1483
 
1484
		 tg_par = old_par;
1485
 
1486
		 if (reh != 1)			// Pauschalraten
1487
                 {
1488
		    kzi = DTable.kapital * TpPars->zssoll * ((double)t1 *
1489
	                  (divisor - (double)t2 * TpPars->zssoll) -
1490
		          (double)t2 * (divisor - (double)t1 * TpPars->zssoll)) /
1491
		          ((divisor - (double)t1 * TpPars->zssoll) *
1492
			  (divisor - (double)t2 * TpPars->zssoll));
1493
                 }
1494
		 else                           // Kapitalraten
1495
		    kzi = DTable.kapital * t1 * TpPars->zssoll / divisor;
1496
 
1497
		 kzi = runden (kzi, rund_fakt);
1498
		 zins += kzi;
1499
 
1500
		 if (reh != 1)
1501
		 {
1502
                    tilg -= kzi;
1503
		    DTable.rkapi = DTable.kapital - tilg;
1504
                 }
1505
	      }
1506
 
1507
	      DTable.kapital -= tilg;
1508
	      r_dat = rat_dat[r_ind];
1509
 
1510
	      if (i == (index - 2))
1511
	      {
1512
	         DTable.rate = DTable.kapital;
1513
		 TpPars->lrate = DTable.rate;
1514
	         DTable.zinsen = 0.0;
1515
	         DTable.tilg = DTable.kapital;
1516
	         DTable.rkapi = 0.0;
1517
	      }
1518
	      else
1519
	      {
1520
	         DTable.rate = runden (sumrat, rund_fakt);
1521
	         DTable.zinsen = zins;
1522
	         DTable.tilg = tilg;
1523
	      }
1524
 
1525
	      TpPars->gesamt += zins;		/* Gesamtbelastung */
1526
 
1527
	      tmpFile.flush();
1528
	      lseek (fd, loff, 0);
1529
	      /* Füllen der Struktur */
1530
	      old_tab.tilg = tilg;
1531
	      old_tab.rate = 0.0;
1532
	      old_tab.zinsen = zins;
1533
 
1534
              if (reh == 1)
1535
		 old_tab.rkapi = old_tab.kapital;
1536
              else
1537
		 old_tab.rkapi = old_tab.kapital + zins;
1538
 
1539
	      write (fd, &old_tab, sizeof (DTABLE));
1540
	      old_tab.kapital = DTable.kapital;
1541
	      old_tab.datum = DTable.datum;
1542
	      lseek (fd, offset, 0);
1543
	      loff = offset;
1544
 
1545
//              if (reh == 1)			// Kapitalraten
1546
		 kap = DTable.kapital;
1547
 
1548
	      zins = 0.0;
1549
	      tilg = 0.0;
1550
	      sumrat = 0.0;
1551
	      a_ind++;
1552
	      ab_tag = tageber (ab_dat[a_ind]);
1553
	   } /* end if */
1554
 
1555
	   if (DTable.datum <= ab_dat[0] && DTable.datum < TpPars->dvon &&
1556
	       DTable.kz == 'R')
1557
	   {
1558
	      if (TpPars->fixrate)
1559
		 Abzug++;
1560
	      else
1561
	         real_rat--;
1562
 
1563
	      continue;
1564
           }
1565
 
1566
	   write (fd, &DTable, sizeof (DTABLE));
1567
	   offset += (long)sizeof (DTABLE);
1568
	} /* end for */
1569
 
1570
	if (TpPars->fixrate == TRUE)
1571
	   TpPars->dbis = rat_dat[r_ind-1];
1572
 
1573
	TpPars->anzraten = real_rat;
1574
	DTable.datum = (long)real_rat;		/* Laufzeit */
1575
	DTable.kz = 'E';			/* Ergebnis */
1576
	DTable.kapital = TpPars->rahmen;
1577
	DTable.tilg = TpPars->gesamt;
1578
	DTable.rate = 0.0;
1579
	TpPars->ezins = TpPars->gesamt - TpPars->rahmen;
1580
 
1581
	if (TpPars->zuschprz > 0.0)
1582
	   TpPars->zuschuss = runden (TpPars->ezins / 100 * TpPars->zuschprz, rund_fakt);
1583
	else
1584
	   TpPars->zuschuss = 0.0;
1585
 
1586
	DTable.zinsen = kzi;
1587
	TpPars->gesamt -= TpPars->zuschuss;
1588
 
1589
	// Annuitätenzuschuß berechnen und anzeigen
1590
 
1591
	if (TpPars->zuschannu > 0.0 && TpPars->gesamt > 0.0)
1592
	{
1593
	   TpPars->anzuschuss = TpPars->ergrate / 100.0 * TpPars->zuschannu;
1594
	   TpPars->antotal = TpPars->anzuschuss * ((double)real_rat - 1.0) + (TpPars->lrate / 100.0 * TpPars->zuschannu);
1595
	   TpPars->antotal -= TpPars->zuschuss;
1596
	}
1597
	else
1598
	   TpPars->anzuschuss = TpPars->antotal = 0.0;
1599
 
1600
	DTable.rkapi = TpPars->lrate;
1601
	write (fd, &DTable, sizeof (DTABLE));
1602
	tmpFile.flush();
1603
	lseek (fd, 0L, 0);
1604
	write (fd, TpPars, sizeof (TPPARS));
1605
	tmpFile.close ();
1606
	return 0;
1607
}
1608
 
1609
void TRech::init_global_vars ()
1610
{
1611
int i;
1612
 
1613
	ab_tag = 0L;
1614
	zi_rat = 0.0;
1615
	zi_kap = 0.0;
1616
	dat_par = 0L;
1617
 
1618
	for (i = 0; i < 1200; i++)
1619
	{
1620
	   rat_dat[i] = 0L;
1621
	   ab_dat[i] = 0L;
1622
	   rat_anz[i] = 0L;
1623
	}
1624
}