Subversion Repositories public

Rev

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

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